RabbitMQ---死信队列和延迟队列

发布时间:2026/10/1 7:43:58
RabbitMQ---死信队列和延迟队列 (一).死信队列1.概念死信指的就是因为各种原因导致消息无法被消息这个消息就被称为“死信”。死信队列指的就是当消息在一个队列中变成死信之后这个消息能被被重新发送到另一个交换机中这个交换器就是死信交换机绑定的队列就是死信队列。消息变成死信一般有三种情况①.消息被拒绝并且设置requeue参数为false(不重新发送不重新入队)②.消息过期③.队列达到最大长度2.演示(1).声明队列和交换机(2).发送消息①.消息过期导致存入死信队列刚发送消息的时候发现在normal.queue中是有一条消息的当到达过期时间后发现normal.queue消息已经没有了消息被发送至dl.queue中了②.消息被拒绝并且设置requeue参数为false导致存入死信队列必须将requeue设置为false因为如果设置为true那么消息会重新入队如果是因为代码逻辑问题导致重新入队那么无论入队多少次都不会正常处理消息此时生产者就会不断地生产该消息就会导致消息积压。上图是生产者的代码上图是消费者代码在测试之前死信队列和正常的队列都是没有消息的上图是测试之后后端打印的日志可以发现消息被转发到了死信队列中③.队列达到最大长度导致存放存入死信队列通过设置maxLength()方法设置该队列最多存放10条消息在发送消息的时候直接发送20条消息将消费者逻辑先注释掉可以发现消息已经全部发过去了可以看到正常队列和死信队列中都有10条消息上图是Web管理页面标签和代码的对应关系3.总结1.死信是MQ中的一种特殊消息它指的是那些无法被正常消费或者处理的消息在RabbitMQ中死信队列用于存储这些死信消息。事实上死信队列本质上就是一个普通的队列它需要配合死信交换机来使用当消息成为死信后会被转发到死信交换机再路由到死信队列2.死信的来源主要有三种。①.当消息在队列中的存活时间超过了设定的TTL此时消息就过期了就会存放进死信队列。②.当消费者在处理消息的时候因为某些原因导致拒绝处理该消息此时如果不重新入队(requeuefalse)的话消息也会成为死信。③.当队列达到最大长度无法再容纳新的消息时新的消息也会被处理为死信3.死信队列的应用场景主要有以下几个。①.应用程序可以通过消费死信队列中的内容来分析当时所遇到的异常情况进而可以改善和优化系统。②.死信队列可以将死信消息重新发送到原队列或者另一个队列进行重试处理③.死信队列可以直接丢弃这些无法处理的消息来避免这些死信消息占用系统资源。(二).延迟队列1.概念延迟队列如果消息发出后并不想让消费者立刻拿到消息而是等待特定时间后消费者等待特定时间后消费者才能拿到这个消息进行消费。但是RabbitMQ并没有给我们提供延迟队列。通常情况下我们通过两种方式显示延迟队列的效果。一种方式是通过TTL死信队列的方式实现另一种是通过RabbitMQ提供的延迟队列插件来实现。2.TTL死信队列实现通过在正常队列中设置过期时间达到过期时间之后转发到死信交换机然后由死信交换机转发到死信队列然后消费者从死信队列中消费消息从而达到延迟队列的效果。(1).代码实现这里还是沿用死信队列的代码生产者消费者上图是测试结果可以发现结果是符合我们的预期的(2).存在的问题通过一个案例来看上图是生产者代码上图是消费者代码当进行测试的时候可以发现我们先发送的过期时间为10s的消息后发送的过期时间为5s的消息虽然我们两条消息设置的过期时间不一致但是RabbitMQ在处理的时候5s的TTL消息会在10s的TTL消息过期之后才进行处理此时延迟功能就出现了问题3.延迟队列插件(1).下载插件并上传服务器发布 · rabbitmq/rabbitmq-delayed-message-exchange --- Releases · rabbitmq/rabbitmq-delayed-message-exchange通过上面的链接下载插件然后我们需要在/usr/lib/rabbitmq目录下创建一个plugins文件夹然后将我们刚刚下载好的插件放到文件夹中然后通过“rabbitmq-plugins enable rabbitmq_delayed_message_exchange”命令启用该插件。通过“rabbitmq-plugins list”命令查看插件列表可以看到我们的插件就启动起来了(2).验证插件我们可以在Web管理页面上查看。新建交换机时查看是否有延迟消息选项如果有就说明已经正常运行了。(3).基于延迟插件实现延迟队列生产者消费者可以发现是可以测试成功的4.总结延时队列是一个特殊的队列当消息发送之后并不会立刻发送给消费者而是等待特定的时间才发送给消费者。延时队列的场景有很多例如①.订单十分钟内未支付自动取消②.用户注册成功后3天后发送调查问卷等等。RabbitMQ自身通过两种方式实现了延迟队列第一种是通过“TTL”和“死信队列”实现这样的实现方式比较灵活不需要额外的插件。但是会存在消息的顺序问题如果队列中的消息的过期时间不一致会出现消息阻塞问题导致延迟时间不准。同时我们需要额外的逻辑来处理死信队列中的消息。总之“TTL”“死信队列”的原理是消息达到TTL之后变成死信由死信交换机路由到死信队列我们消费死信队列完成延时任务。第二种是使用官方提供的延迟插件来实现这样的实现方式简化了延迟消息的实现同时避免了DLX的时序问题。但是这个插件只适应于特定版本