欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 明星 > RabbitMQ实践——使用死信机制对异常消息进行处理

RabbitMQ实践——使用死信机制对异常消息进行处理

2025/4/6 15:32:02 来源:https://blog.csdn.net/breaksoftware/article/details/139709498  浏览:    关键词:RabbitMQ实践——使用死信机制对异常消息进行处理

大纲

  • 独立的死信交换器
    • 创建死信交换器
    • 死信交换器绑定队列
    • 创建自动路由到死信交换器上的队列
    • 实验
  • 重用原始交换器
    • 简单案例
      • 测试
    • 复杂案例
      • 新建交换器
      • 新建队列
      • 绑定
      • 测试

在《RabbitMQ实践——对不可路由的消息的处理方法》一文中,我们使用备用交换器来处理当前交换器不可路由的消息。这类消息的异常往往出现在Routing key这类会影响路由的字段上,而如果消息体自身有问题——结构不符合业务约定、某个字段值不合法,则怎么处理呢?是抛弃还是让其继续保留在队列中?上述两种方式都不太好:如果抛弃则会让我们丧失分析异常的机会;如果保留在队列中则会堆积,影响后续处理效率。
RabbitMQ提供了死信机制来辅助我们处理这类消息。其基本原理就是在业务逻辑判断这些消息存在异常的情况下,让这些消息路由到另外一个独立的队列中。这样后续维护人员可以从这个队列中获取数据进行分析,而不会影响线上业务。
RabbitMQ提供了两个死信机制。
在做这次实验之前,我们先创建一个普通队列dead_letter_queue,用于保存死信。
在这里插入图片描述

独立的死信交换器

在这里插入图片描述
如上图,消费者在从正常队列中获取消息。突然发现一个异常消息,它就拒绝该消息,并让RabbitMQ服务不要再发送这条消息。这样RabbitMQ服务会将这条退回到队列中的消息路由到一个独立的死信交换器上,交由它来路由到死信队列。

创建死信交换器

为了让死信交换器可以接收所有消息,我们使用了不用做规则匹配的fanout类型交换器。从下图可以看出,死信交换器(我们给它命名dead.letter)和其他交换器没什么区别。
在这里插入图片描述

死信交换器绑定队列

我们让这个交换器绑定到之前创建的死信队列dead_letter_queue上。
在这里插入图片描述

创建自动路由到死信交换器上的队列

我们创建一个名字叫queue_with_dead_letter_exchange,x-dead-letter-exchange参数值是之前创建的死信交换器dead.letter的队列。
在这里插入图片描述

实验

在默认交换器中,我们发布一条消息到queue_with_dead_letter_exchange队列上。
在这里插入图片描述
在这里插入图片描述
然后在该队列页面中,接收这条消息,但是告诉RabbitMQ服务,消费者拒绝这条消息,同时不要重发。
在这里插入图片描述
这个时候queue_with_dead_letter_exchange队列中就不存在这条消息了。
在这里插入图片描述
它被路由到这条队列(queue_with_dead_letter_exchange)通过x-dead-letter-exchange参数指定的死信交换器dead.letter上。然后死信交换器将其路由到死信队列dead_letter_queue上。
在这里插入图片描述
在这里插入图片描述

重用原始交换器

之前的案例,我们需要新建一个死信交换器、绑定关系、死信队列才能完成死信所有功能。
而RabbitMQ还提供了一种重用原始交换器的功能,我们只要新建绑定关系、死信队列就可以完成所有功能。
在这里插入图片描述

简单案例

因为之前使用的是默认交换器。它并不需要设定绑定关系,而是自动通过各个队列名作为Routing key,将消息路由到队列上。这样在简单案例中,我们省去建立绑定关系这个步骤。
但是我们还是要新建一个队列,它需要将x-dead-letter-exchange设定为消息发送来源的交换器,还要将x-dead-letter-routing-key设定为重写消息的Routing key(指向死信队列),让消息在被消费者拒绝且不再重发后,通过这条消息来源的交换器,再路由到死信队列。
因为我们使用的是默认交换器,所以下图中x-dead-letter-exchange是空值,x-dead-letter-routing-key是死信队列的名称。
在这里插入图片描述

测试

在默认交换器中,我们给刚创建的队列发布一条消息。
在这里插入图片描述
在这里插入图片描述
然后消费者拒绝这条消息,并让RabbitMQ不再重发。
在这里插入图片描述
这条消息就被路由到死信队列中了
在这里插入图片描述
在这里插入图片描述

复杂案例

因为之前我们直接使用了默认交换器,省去了Banding关系这个环节。
本例我们将使用一个稍微常见的组织形式。

新建交换器

我们创建一个名字叫direct.with.dead.letter的交换器。该交换器很普通,就是一个direct类型的交换器。
在这里插入图片描述

新建队列

新建一个名字叫common_queue的队列。指定x-dead-letter-exchange是上一步创建的交换器名direct.with.dead.letter;指定被拒绝切不重发的消息的Routing key被重写为to.dead.letter。
在这里插入图片描述
死信队列就沿用之前创建的队列dead_letter_queue。

绑定

新建两个绑定关系:

  • to.common的Routing key被路由到队列common_queue。
  • to.dead.letter的Routing key被路由到队列dead_letter_queue。
    在这里插入图片描述

测试

我们先给common_queue发布一条消息。
在这里插入图片描述
在这里插入图片描述
然后消费者拒绝这条消息,并通知RabbitMQ不再重发。
在这里插入图片描述
这样,这条消息的Routing key就被重写为to.dead.letter,然后被交换器路由到死信队列。
在这里插入图片描述
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词