RabbitMQ用法
- 前言
- 一、rabbitmq配置
- 二、队列交换机配置
- 1.RabbitmqConfig类配置队列,路由,交换机
- 2.生产消息
- 3.消费消息
- 4.消息确认和丢弃
- 4.工具测试
- 总结
前言
提示:上一篇说完了rabbitmq基本知识,这篇文章主要是通过Topic类型来生产和消费消息
一、rabbitmq配置
1. application.properties配置文件
# rabbitmq
# 配置虚拟机
spring.rabbitmq.virtual-host=/
# 开启消息确认机制 confirm 异步
spring.rabbitmq.publisher-confirm-type=correlated
# 开启return机制
spring.rabbitmq.publisher-returns=true
# 消息开启手动确认
spring.rabbitmq.listener.simple.acknowledge-mode=manual
spring.rabbitmq.host=192.168.100.49
spring.rabbitmq.port=5672
spring.rabbitmq.username=open_sa
spring.rabbitmq.password=open_sa
2. pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
二、队列交换机配置
1.RabbitmqConfig类配置队列,路由,交换机
代码如下(示例):
/**
* @param
* @return
* @Description 绑定队列
* @author lihongqiang
* @date 2021-6-4 17:00
*/
@Bean
public Queue queueTopicStructuredProjectData() {
return new Queue("que.data");
}
/**
* @param
* @return
* @Description 绑定key
* @author lihongqiang
* @date 2021-6-4 17:01
*/
@Bean
public TopicExchange exchangeTopicStructuredProjectData() {
return new TopicExchange("topic.date");
}
/**
* @param
* @return
* @Description 绑定 exchange and queue *(星号):可以(只能)匹配一个单词 #(井号):可以匹配多个单词(或者零个)
* @author lihongqiang
* @date 2021-6-4 16:57
*/
@Bean
public Binding bindingTopic() {
return BindingBuilder.bind(queueTopicStructuredProjectData()).to(exchangeTopicStructuredProjectData()).with("que.data");
}
注意:绑定队列规则时#和*用法为:with(“que.#”)类似
2.生产消息
生产者生产消息发送至队列中:
@Resource
private RabbitTemplate rabbitTemplate;
@Override
public void sendWork(String str) {
rabbitTemplate.convertAndSend("que.data", str );
}
public void sendTopic() {
String str = "消费者1接收到:测试topic类型";
rabbitTemplate.convertSendAndReceive("e-exchange", "que.data", str);
}
这两种方法都可以发送消息,此处可以自己用postman调用模拟发送消息。convertSendAndReceive第一个参数为交换机
3.消费消息
消费者监听队列获取消息:
@RabbitListener(queues = "que.data")
public void receiveMsg1(Message message, Channel channel) throws IOException {
log.info("消费者1接收到:{}" , new String(message.getBody()));
}
4.消息确认和丢弃
消息确认有手动和自动两种方式:
- 自动确认
- 手动确认
配置文件中开启手动确认方式
spring.rabbitmq.listener.simple.acknowledge-mode=manual
- 确认消息
ack表示确认消息。multiple:false只确认该delivery_tag的消息,true确认该delivery_tag的所有消息
channel.basicAck(msg.getMessageProperties().getDeliveryTag(),false);
- 拒绝消息
Reject表示拒绝消息。requeue:false表示被拒绝的消息是丢弃;true表示重回队列
channel.basicReject(msg.getMessageProperties().getDeliveryTag(),false);
- 拒绝消息
nack表示拒绝消息。multiple表示拒绝指定了delivery_tag的所有未确认的消息,false表示不是重回队列
channel.basicNack(msg.getMessageProperties().getDeliveryTag(),false,false);
- 上面消费者接收到消息后,可以按下列方式处理
log.info("消费者1接收到:{}" , new String(message.getBody()));
try{
String str = new String(message.getBody());
if(true){
//数据正确处理后
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}else {
//数据处理失败需要丢弃或重回队列时
//方式二选一,具体要看业务逻辑
//拒绝消息,false消息丢弃
channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
//拒绝消息,拒绝指定了delivery_tag的所有未确认的消息,false不回队列
channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
}
}catch (Exception e){
//方式二选一,具体要看业务逻辑
//拒绝消息,false消息丢弃
channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
//拒绝消息,拒绝指定了delivery_tag的所有未确认的消息,false不回队列
channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
}
4.工具测试
postman调用生产消息(模拟生产者发送消息到队列,消费者消费队列消息):
消费者接收到的消息为:
总结
rabbitmq其它类型用法只是绑定交换机和队列时有一定的区别,重点在于生产者消息发送之后,消费者是否消费成功,以及消息重复消费时如何处理。
此种配置是集成springboot中,如果你的代码中需要连接的交换机和队列不存在,将自动创建。
rabbitMq的重点在于消息如何不重复消费,消费失败的消息如何处理,以及多消费者消息如何不重复消费