RabbitMQ消息確認機制

生產者發送消息出去之後,不知道到底有沒有發送到RabbitMQ服務器, 默認是不知道的。而且有的時候我們在發送消息之後,後面的邏輯出問題了,我們不想要發送之前的消息了,需要撤回該怎麼做。

解決方案:

 1.AMQP 事務機制   
 2.Confirm 模式 事務模式:  
 txSelect  將當前channel設置爲transaction模式  
 txCommit  提交當前事務  
 txRollback  事務回滾

AMQP 事務機制

生產者

public class Producer {
	private static final String QUEUE_NAME = "test_queue";

	public static void main(String[] args) throws IOException, TimeoutException {
		// 1.獲取連接
		Connection newConnection = MQConnectionUtils.newConnection();
		// 2.創建通道
		Channel channel = newConnection.createChannel();
		// 3.創建隊列聲明
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		// 將當前管道設置爲 txSelect 將當前channel設置爲transaction模式 開啓事務
		channel.txSelect();
		String msg = "test_selt791";
		try {
			// 4.發送消息
			channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
			// int i = 1 / 0;
			channel.txCommit();// 提交事務
			System.out.println("生產者發送消息:" + msg);
		} catch (Exception e) {
			System.out.println("消息進行回滾操作");
			channel.txRollback();// 回滾事務
		} finally {
			channel.close();
			newConnection.close();
		}

	}

}

消費者

// 1.獲取連接
		Connection newConnection = MQConnectionUtils.newConnection();
		// 2.創建通道
		Channel channel = newConnection.createChannel();
		// 3.創建隊列聲明
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		// confirm機制
		channel.confirmSelect();
		String msg = "test_selt791";
		// 4.發送消息
		channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
		System.out.println("生產者發送消息:" + msg);
		if (!channel.waitForConfirms()) {
			System.out.println("消息發送失敗!");
		} else {
			System.out.println("消息發送成功!");
		}
		channel.close();
		newConnection.close();

SpringBoot整合RabbitMQ

生產者

Maven環境依賴

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>

		<!-- springboot-web組件 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 添加springboot對amqp的支持 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
		</dependency>
		<!--fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.49</version>
		</dependency>
	</dependencies>

application.yml

spring:
  rabbitmq:
  ####連接地址
    host: 127.0.0.1
   ####端口號   
    port: 5672
   ####賬號 
    username: guest
   ####密碼  
    password: guest
   ### 地址
    virtual-host: /

交換機綁定隊列

@Component
public class FanoutConfig {

	// 郵件隊列
	private String FANOUT_EMAIL_QUEUE = "fanout_eamil_queue";

	// 短信隊列
	private String FANOUT_SMS_QUEUE = "fanout_sms_queue";
	// 短信隊列
	private String EXCHANGE_NAME = "fanoutExchange";

	// 1.定義隊列郵件
	@Bean
	public Queue fanOutEamilQueue() {
		return new Queue(FANOUT_EMAIL_QUEUE);
	}

	@Bean
	public Queue fanOutSmsQueue() {
		return new Queue(FANOUT_SMS_QUEUE);
	}

	// 2.定義交換機
	@Bean
	FanoutExchange fanoutExchange() {
		return new FanoutExchange(EXCHANGE_NAME);
	}

	// 3.隊列與交換機綁定郵件隊列
	@Bean
	Binding bindingExchangeEamil(Queue fanOutEamilQueue, FanoutExchange fanoutExchange) {
		return BindingBuilder.bind(fanOutEamilQueue).to(fanoutExchange);
	}

	// 4.隊列與交換機綁定短信隊列
	@Bean
	Binding bindingExchangeSms(Queue fanOutSmsQueue, FanoutExchange fanoutExchange) {
		return BindingBuilder.bind(fanOutSmsQueue).to(fanoutExchange);
	}
}

生產者投遞消息

@Component
public class FanoutProducer {
	@Autowired
	private AmqpTemplate amqpTemplate;

	public void send(String queueName) {
		String msg = "my_fanout_msg:" + new Date();
		System.out.println(msg + ":" + msg);
		amqpTemplate.convertAndSend(queueName, msg);
	}
}

控制層調用代碼

@RestController
public class ProducerController {
	@Autowired
	private FanoutProducer fanoutProducer;

	@RequestMapping("/sendFanout")
	public String sendFanout(String queueName) {
		fanoutProducer.send(queueName);
		return "success";
	}
}

消費者

Maven環境依賴

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>

		<!-- springboot-web組件 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 添加springboot對amqp的支持 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
		</dependency>
		<!--fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.49</version>
		</dependency>
	</dependencies>

郵件消費者

@Component
@RabbitListener(queues = "fanout_eamil_queue")
public class FanoutEamilConsumer {
	@RabbitHandler
	public void process(String msg) throws Exception {
		System.out.println("郵件消費者獲取生產者消息msg:" + msg);
	}
}

短信消費者

@Component
@RabbitListener(queues = "fanout_sms_queue")
public class FanoutSmsConsumer {
	@RabbitHandler
	public void process(String msg) {
		System.out.println("短信消費者獲取生產者消息msg:" + msg);
	}
}

application.yml

spring:
  rabbitmq:
  ####連接地址
    host: 127.0.0.1
   ####端口號   
    port: 5672
   ####賬號 
    username: guest
   ####密碼  
    password: guest
   ### 地址
    virtual-host: /
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章