rabbitmq五种模式详解(含实现代码) (7)

在我们的rabbit队列配置类里设置RabbitTemplate
举例:

package com.gmtgo.demo.topic; import com.gmtgo.demo.config.RabbitConfirmCallback; import com.gmtgo.demo.config.RabbitConfirmReturnCallBack; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.TopicExchange; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; /** * @author 大帅 */ @Configuration public class TopicQueueConfig { @Autowired private RabbitTemplate rabbitTemplate; @PostConstruct public void initRabbitTemplate() { // 设置生产者消息确认 rabbitTemplate.setConfirmCallback(new RabbitConfirmCallback()); rabbitTemplate.setReturnCallback(new RabbitConfirmReturnCallBack()); } /** * 声明队列名. */ private final String topic1 = "topic_queue_1"; private final String topic2 = "topic_queue_2"; /** * 声明交换机的名字. */ private final String topicExchange = "topicExchange"; /** * 声明队列. * * @return */ @Bean public Queue topicQueue1() { return new Queue(topic1); } @Bean public Queue topicQueue2() { return new Queue(topic2); } /** * 声明路由交换机. * * @return */ @Bean public TopicExchange topicExchange() { return new TopicExchange(topicExchange); } /** * 队列绑定交换机,指定routingKey,也可在可视化工具中进行绑定. * * @return */ @Bean Binding bindingTopicExchange1(Queue topicQueue1, TopicExchange exchange) { return BindingBuilder.bind(topicQueue1).to(exchange).with("topic.keyA"); } /** * 队列绑定交换机,指定routingKey,也可在可视化工具中进行绑定. * 绑定的routing key 也可以使用通配符: * *:匹配不多不少一个词 * #:匹配一个或多个词 * * @return */ @Bean Binding bindingTopicExchange2(Queue topicQueue2, TopicExchange exchange) { return BindingBuilder.bind(topicQueue2).to(exchange).with("topic.#"); } }

启动项目发送消息,消息被正常消费,confim回调返回ack=true如果我们将exchange修改,发送到一个不存在的exchange中,会怎么样呢?

会发现confirm回调为false,打印出结果为不存在topicExchange1111的交换机

如果我们在消费端处理逻辑时出错会怎么样呢?修改消费端代码我们在消费时让它报错


confirm回调为true,但是在rabbitmq的web界面会发现存在5条没有消费的消息

如果我们把

channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);

中最后一个参数改为false呢,会发现在web管理界面没有未被消费的消息,说明这条消息已经被摒弃。

实际开发中,到底是打回到队列呢还是摒弃,要看自己的需求,但是打回队列应该有次数限制,不然会陷入死循环
继续测试,将routingKey修改为一个没有的key,

7.5 结论

如果消息没有到exchange,则confirm回调,ack=false

如果消息到达exchange,则confirm回调,ack=true

exchange到queue成功,则不回调return

exchange到queue失败,则回调return

8. 项目示例代码:

下载地址:springboot-rabbitmq-demo_1619322789961

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgyzj.html