生產者發送消息出去之後,不知道到底有沒有發送到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: /