rabbitmq接收消息_Springboot2.2.6+RabbitMQ消息异常处理

本文详细介绍了在Springboot2.2.6中使用RabbitMQ进行消息异常处理的方法,包括消息落地保存、设置消息过期时间和配置死信队列,以确保消息系统的稳定和高效运行。
摘要由CSDN通过智能技术生成

接续之前文章

Springboot2.2.6构建RabbitMQ消息接收端

小T说:消息中间件,构建RabbitMQ消息发布端代码


大家好,我是技术人小Top

今天咱们来介绍如何使用RabbitMQ构建消息异常处理 ^-^

5442668d39da4b0b93bc23dfdefa4292.png

RabbitMQ官网:www.rabbitmq.com

上次介绍了Spring2.26如何构建RabbitMQ消息接收端

具体到应用开发,需要使用RabbitMQ API来实现具体业务场景

现在开始进入实战

消息是否落地保存

建议:落地保存

1、落地保存的好处

  • 消息保存在数据库中方便人工和程序处理

虽然RabbitMQ具备消息持久化的特性,但是它毕竟不是存储设备。相比较数据库而言,数据的可读性、易用性和稳定性都要逊色。

  • 事后方便业务对账

通常消息发送和接收确认后,RabbitMQ中不再持久化消息了。这时一旦业务对账出现了问题,消息不存在则无法追溯,无法对异常情况进行复位排差。

2、落地保存的具体位置/时机

详见本号之前的Springboot2.2.6构建RabbitMQ消息发布端代码、Springboot2.2.6构建RabbitMQ消息接收端代码文章

  • 发送消息到Exchange成功时
  • 发送消息到Exchange失败时
  • 发送消息到Queue失败时
  • 接收消息成功时
  • 接收消息失败时

消息是否设置过期

根据实际需要来决定

1、设置过期时间的好处

  • 消息及时释放/删除会减轻RabbitMQ对磁盘占用的压力

从业务角度来说,消息的持久化毕竟是短暂的或瞬态的,不需要像数据库那样永久保存数据

  • 即使出现异常也不会对RabbitMQ造成磁盘压力

只要配合消息落地,就算有异常产生,在设计层面可以依赖数据库保证数据的永久可追溯

2、设置过期时间的实现

  • 对Queue或Message都可设置过期时间

大多数场景会对Queue设置过期时间。当同时设置过期时间时,以最小的过期时间为准

Queue userQueue1 = QueueBuilder.durable(MQ_QUEUE_USER1)        //Todo: ttl()方法用于设置Queue的过期时间        .ttl(300000).build();

消息是否设置死信队列

根据实际需要来决定

1、设置死信队列的好处

  • 保证消费的队列没有垃圾数据

由于通常消息是持久化的,原队列也就是业务队列中的数据会不断进入新的消息。这时如果存在异常消息(也就是消费端处理过程中发生异常而无法处理)长时间存放在原队列是没有意义的。因为这通常需要消费端排查问题并修复代码。

  • 保证消费的队列高效运行

由于没有死信(处理不了的异常消息),队列消费的速度会很高效。反之,如果重复入队,效率会降低。如果不重复入队,需要有追溯机制来跟进和解决异常问题。

  • 便于保存异常消息并定位问题

2、设置死信队列的实现

之前的AMQP协议、模型及RabbitMQ常用组件文章中发过这样一张图,说明了AMQP的工作原理

baad673f715cfe77e2088dfd07683ce6.png

在此图基础上,我们把死信交换机和死信队列加上,一张图就能看明白了(请关注红色箭头)

1、当**Consumer1**从**Queue**(user1)中接收消息失败时,调用API告诉RabbitMQ抛弃错误消息

2、由于**Queue**(user1)设置了**死信交换机**,被抛弃的消息成为死信进入死信交换机user1DLXExchange

3、由于**Queue**(user1DLX)绑定了**死信交换机**,死信队列会接收到被抛弃的消息

9e48a1f907625a0ff1521bc1aa46c45e.png

我们将之前文章中的代码稍加改造就可以了

//Todo: 增加死信交换机和死信队列的命名/** * 死信交换机user1名称 */public static final String MQ_DLX_EXCHANGE_USER1 = "user1DLXExchange";/** * 死信交换机user2名称 */public static final String MQ_DLX_EXCHANGE_USER2 = "user2DLXExchange";/** * 死信队列user1名称 */public static final String MQ_DLX_QUEUE_USER1 = "user1DLX";/** * 死信队列user2名称 */public static final String MQ_DLX_QUEUE_USER2 = "user2DLX";@Beanpublic Declarables declarables() {    //Todo: user1指定死信交换机deadLetterExchange    Queue userQueue1 = QueueBuilder        .durable(MQ_QUEUE_USER1)        .deadLetterExchange(MQ_DLX_EXCHANGE_USER1)        .build();    //Todo: user2指定死信交换机deadLetterExchange    Queue userQueue2 = QueueBuilder        .durable(MQ_QUEUE_USER2)        .deadLetterExchange(MQ_DLX_EXCHANGE_USER2)        .build();    FanoutExchange fanoutExchange = ExchangeBuilder.        fanoutExchange(MQ_FANOUT_EXCHANGE_USER)        .durable(true)        .build();    DirectExchange directExchange = ExchangeBuilder        .directExchange(MQ_FANOUT_EXCHANGE_TEST)        .durable(true)        .build();    //Todo: 定义死信队列    Queue userDLXQueue1 = QueueBuilder        .durable(MQ_DLX_QUEUE_USER1)        .ttl(300000)        .build();    Queue userDLXQueue2 = QueueBuilder        .durable(MQ_DLX_QUEUE_USER2)        .ttl(300000)        .build();    //Todo: 定义死信队列交换机    FanoutExchange dlxUser1Exchange = ExchangeBuilder        .fanoutExchange(MQ_DLX_EXCHANGE_USER1)        .durable(true)        .build();    FanoutExchange dlxUser2Exchange = ExchangeBuilder        .fanoutExchange(MQ_DLX_EXCHANGE_USER2)        .durable(true)        .build();    return new Declarables(userQueue1, userQueue2, fanoutExchange, directExchange,                           userDLXQueue1, userDLXQueue2, dlxUser1Exchange, dlxUser2Exchange,                           BindingBuilder.bind(userQueue1).to(fanoutExchange),                           BindingBuilder.bind(userQueue2).to(fanoutExchange),                           BindingBuilder.bind(userDLXQueue1).to(dlxUser1Exchange),                           BindingBuilder.bind(userDLXQueue2).to(dlxUser2Exchange));}

小结

今天主要介绍了如何构建RabbitMQ异常处理

小伙伴们都了解了吗?

下次小Top将继续介绍RabbitMQ开发

对于今天的内容有任何疑问或问题,欢迎留言或讨论 ^-^

本文由星空奇点原创,欢迎关注,带你一起长知识!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值