生产者发送消息出去之后,不知道到底有没有发送到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: /