设为首页 收藏本站
查看: 1373|回复: 0

[经验分享] 关于 RabbitMQ 的 Dead-Letters-Queue “死信队列”

[复制链接]

尚未签到

发表于 2017-7-2 11:23:47 | 显示全部楼层 |阅读模式
来自一个队列的消息可以被当做‘死信’,即被重新发布到另外一个“exchange”去,这样的情况有:

  • 消息被拒绝 (basic.reject or basic.nack) 且带 requeue=false 参数
  • 消息的TTL-存活时间已经过期
  • 队列长度限制被超越(队列满)


Dead letter exchanges (DLXs) are normal exchanges.

For any given queue, a DLX can be defined by clients using the queue's arguments, or in the server using policies.

Dead Letter Pattern
     “死信”模式指的是,当消费者不能处理接收到的消息时,将这个消息重新发布到另外一个队列中,等待重试或者人工干预。
这个过程中的exchange和queue就是所谓的"Dead Letter Exchange 和 Queue"。
     关键是如何区分“消费失败”和“处理失败”?消费失败需要送到死信队列,而处理失败不需要。大部分情况都属于“处理失败”。

Dead-Letter-Exchange, routing-key, queue 都可以从 rabbitmq 的管理后台配置。

如果用 Spring-rabbitmq 来使用 Dead-Letter-Exchange 和 Queue 需要对。
     从 3.9 Exception Handling 可以知道,设置 defaultRequeueRejected = false 会丢弃消息或者重新发布到死信队列中。
     如果是 Convert 出现异常,那么会直接 "reject-dont-requeue".


<rabbit:listener-container defaultRequeueRejected="false"  connection-factory="connectionFactory">
  <rabbit:listener ref="listener" method="listen" queue-names="async_request_queue" />
</rabbit:listener-container>


     也可以在 handler 中抛出 "AmqpRejectAndDontRequeueException" 来告诉spring容器,不要重新requeue这条消息。

     然后配置 Dead Letter Exchange 并绑定 Dead Letter Queue.

<rabbit:queue name="q.with.dlx">
    <rabbit:queue-arguments>
        <entry key="x-dead-letter-exchange" value="dlx"/>
        <entry key="x-message-ttl" value="10000" value-type="java.lang.Long"/>
    </rabbit:queue-arguments>
</rabbit:queue>

<rabbit:queue name="dlq"/>

<rabbit:direct-exchange name="dlx">
    <rabbit:bindings>
        <rabbit:binding key="q.with.dlx" queue="dlq"/>
    </rabbit:bindings>
</rabbit:direct-exchange>
     如果 exchange 或者 queue 是 镜像/持久的,那么需要先删除再启动 spring-amqp 程序,这样 xml 中的 exchange 和 queue 配置才能生效,
否则服务器端配置不会修改,启动生成者时抛异常,启动失败。
     对于部署,可以考虑使用新队列来避免需要先删除已有队列的问题。

常见问题:
1、consumer启动时报告异常 com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-dead-letter-exchange' for queue 'queue_emailsend_result' in vhost 'host_test': received the value 'dlx' of type 'longstr' but current is none, class-id=50, method-id=10)
     原因:queue已经存在,但是启动 consumer 时试图设定一个 x-dead-letter-exchange 参数,这和服务器上的定义不一样,server 不允许所以报错。如果删除 queue 重新 declare 则不会有问题。或者通过 policy 来设置这个参数也可以不用删除队列。
     参考blog

参考:


    • https://www.rabbitmq.com/dlx.html
    • http://ju.outofmemory.cn/entry/147739
    • http://bitsuppliers.com/dead-lettering-with-rabbitmq/
    • http://bitsuppliers.com/dead-lettering-with-rabbitmq-strategies/
    • http://stackoverflow.com/questions/24858880/spring-rabbittemplate-is-not-creating-dead-letter-queue-with-ttl


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-390288-1-1.html 上篇帖子: RabbitMQ-从基础到实战(4)— 消息的交换(中) 下篇帖子: RabbitMQ的使用(5)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表