DLX,即Dead Letter Exchange死信交换机

概述

队列中的消息可能会变成死信消息(dead-lettered),当发生如下事件时会导致消息变为死信:

  • rejected: the message was rejected with requeue parameter set to false (消息被消费者使用basic.reject或basic.nack方法,并且requeue参数设置为false,通过这种方式进行消息确认)
  • expired: the message TTL has expired (消息过期)
  • maxlen: the maximum allowed queue length was exceeded (消息由于队列长度及容量限制被丢弃的消息)
DLXs(Dead Letter Exchanges)

死信交换器就是普通的交换器,它们可以是任何我们常见的类型,并像往常声明一样。DLX可以通过queue队列的参数来定义,也可以通过policy的方式来定义。

死信交换器的使用方式
  • 声明一个交换器
            channel.exchangeDeclare("some.exchange.name", BuiltinExchangeType.DIRECT);
  • 声明队列时需要设置的参数(此队列不是死信队列)
            Map<String, Object> arguments = Maps.newHashMap();/*** 设置消息发送到队列中在被丢弃之前可以存活的时间,单位:毫秒*/arguments.put("x-message-ttl", 10*60*1000);/*** 设置一个队列多长时间未被使用将会被删除,单位:毫秒*///arguments.put("x-expires", 15*60*1000);/*** queue中可以存储处于ready状态的消息数量*/arguments.put("x-max-length", 6);/*** queue中可以存储处于ready状态的消息占用的内存空间*/arguments.put("x-max-length-bytes", 1024);/*** queue溢出行为,这将决定当队列达到设置的最大长度或者最大的存储空间时发送到消息队列的消息的处理方式;* 有效的值是:drop-head(删除queue头部的消息)、reject-publish(拒绝发送来的消息)、reject-publish-dlx(拒绝发送消息到死信交换器)* 类型为quorum 的queue只支持drop-head;*/arguments.put("x-overflow", "reject-publish");/*** 死信交换器,消息被拒绝或过期时将会重新发送到的交换器*/arguments.put("x-dead-letter-exchange", "some.exchange.name");/*** 当消息是死信时使用的可选替换路由*/arguments.put("x-dead-letter-routing-key", "some-routing-key");
  • 声明死信队列
channel.queueDeclare("some.queue.name", true, false, false, null);
  • 死信队列、交换器、路由绑定
channel.queueBind("some.queue.name", "some.exchange.name", "some-routing-key");
路由死信消息(Routing Dead-Lettered Messages)

死信消息将会被路由到它们的死信交换器

  • 使用其所在队列指定的死信交换器路由,或者,没有设置此项
  • 与最初发布时使用的路由相同

例如:如果你发布一条消息到交换器,使用的路由是foo;但是这条消息是一个死信,它将发送消息到路由是foo的死信交换器;如果队列最初声明的时候已经设置了 x-dead-letter-routing-key 的值为bar,那么消息将会使用路由bar发布到死信交换器上。

​ 注意,如果队列没有设置死信路由关键字,那消息被死信路由时将会使用它自身的原始路由关键字。这包含了CC和BCC头参数设置的路由的关键字。

当死信消息被重新发送时,消息确认机制也会在内部被开启,因此,在原始队列删除这条消息之前,消息最终到达的队列—死信队列必须确认该消息。换句话说,发送队列在接收到死信队列的确认消息之前不会删除原始消息。注意,如果在特殊情况下服务器宕机,那么同样的消息将会在原始队列和死信队列中同时出现。

消息的死信路由可能会形成一个循环。比如,一个队列的死信的消息没有使用指定的死信路由关键字被发送到默认的交换机时。消息在整个循环(消息到达同一个队列两次)中没有被拒绝,那么消息将被丢弃。

死信对消息的影响(Dead-Lettered Effects on Messages)

死信消息修改了它的头部信息:

  • 交换机的名称被修改为最后的死信交换机
  • 路由关键字可能被改为队列指定的死信路由关键字
  • 如果以上发生,名为CC的头参数将被删除
  • 名为BCC的头参数将被删除

进行死信路由时,会给每个死信消息的头部增加一个名为x-death的数组。这个数组包含了过于每次死信路由的信息实体,通过一个键值对{queue, reason}区分。每个实体是一张表,包含了一下的字段信息:

  • queue:消息称为死信时所在队列的名称
  • reason:消息成为死信的原因
  • time:消息成为死信的时间,是一个64位的时间戳
  • exchange:消息被发送的交换机(当消息多次称为死信消息时,该值为死信交换机)
  • routing-keys: 消息被发送时使用的路由关键字,包含了CC关键字但是不包含BCC
  • count:在该队列中消息由于这个原因被死信路由的次数
  • original-expiration(如果消息时因为消息的TTL称为死信时,有该值):消息的原始过期时间属性,这个值在消息被死信路由时将被移除,为了避免消息在其他队列中再次过期

新的信息实体将被发送x-death数组的首位,如果该数组中已经存在同样的队列和同样的死信原因的信息实体,那么该实体的count字段将加1并且实体被移到数组的首位。

reason这个属性的值表示了消息变为死信的原因,有以下几种:

  • rejected:消息被消息者拒绝并且requeue参数值为false
  • expired:消息因为消息的TTL过期
  • maxlen:超过了队列允许的最大长度

当进行消息进行首次路由时,将添加三个顶级的头信息:

  • x-first-death-reason
  • x-first-death-queue
  • x-first-death-exchange

它们与消息进行首次死信路由时,设置的reason, queue, exchange字段值相同。一旦添加,它们值将不会再被修改。

GitHub地址:https://github.com/mingyang66/spring-parent

RabbitMQ学习笔记:死信交换机DLX相关推荐

  1. RabbitMq(十一) 死信交换机DLX介绍及使用

    概述:         死信交换机(DLX dead-letter-exchange)和普通交换机一样,也是一种普通的交换机,只不过一般交换机处理正常的消息,而死信交换机是接收被删除的消息.绑定到死信 ...

  2. RabbitMQ 学习笔记

    RabbitMQ 学习笔记 RabbitMQ 学习笔记 1. 中间件 1.1 什么是中间件 1.2 为什么要使用消息中间件 1.3 中间件特点 1.4 在项目中什么时候使用中间件技术 2. 中间件技术 ...

  3. RabbitMQ学习笔记(高级篇)

    RabbitMQ学习笔记(高级篇) 文章目录 RabbitMQ学习笔记(高级篇) RabbitMQ的高级特性 消息的可靠投递 生产者确认 -- confirm确认模式 生产者确认 -- return确 ...

  4. Rabbitmq学习笔记(尚硅谷2021)

    Rabbitmq学习笔记 (尚硅谷) 1.MQ 的概念 1.1 什么是 MQ? 1.2 为什么要用 MQ? 削峰 解耦 异步 1.3 MQ 的分类 ActiveMQ Kafka RocketMQ Ra ...

  5. Rabbitmq学习笔记教程-尚硅谷

    Rabbitmq学习笔记 (尚硅谷) 尚硅谷 rabbitmq 教程 1.MQ 的概念 1.1 什么是 MQ? 存放消息的队列,互联网架构中常见的一种服务与服务之间通信的方式. 1.2 为什么要用 M ...

  6. RabbitMQ高级特性——死信队列DLX以及代码测试

    大伙可以到我的RabbitMQ专栏获取更多信息 demo示例这里拿 概述 死信队列,缩写DLX(dead letter exchange 死信交换机),当消息称为dead message之后,会被重新 ...

  7. RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决)

    RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决) 参考文章: (1)RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决) (2)https://www.cnblogs. ...

  8. RabbitMQ学习笔记(3)----RabbitMQ Worker的使用

    1. Woker队列结构图 这里表示一个生产者生产了消息发送到队列中,但是确有两个消费者在消费同一个队列中的消息. 2. 创建一个生产者 Producer如下: package com.wangx.r ...

  9. RabbitMQ学习笔记 03、交换机模式(4种)

    文章目录 前言 交换机工作模式(四种) 一.fanout模式 1.1.基本概念 1.2.代码实操 二.direct模式 2.1.基本概念 2.2.代码实操 三.topic模式 3.1.基本概念 3.2 ...

最新文章

  1. centos7 选定默认启动内核,及删除无用内核
  2. java 打包的两种方式
  3. python这个软件学会能做什么工作-学会Python后都能做什么?网友们的回答简直不要太厉害...
  4. python3.6安装pip-python3.6如何安装pip
  5. Spark面对OOM问题的解决方法及优化总结 (转载)
  6. c++ sleep函数_我们如何在C,C ++中控制/安排线程的执行?
  7. 开发这么久你真知道for循环内部执行顺序吗?
  8. Jensen不等式证明
  9. 手把手教你如何破解软件
  10. 2018百度云智峰会,为什么百度大脑站C位?
  11. 论文解读-DeepMove: Predicting Human Mobility with Attentional Recurrent Networks
  12. 2018浙大408考研经验(划掉)个人口胡 普通一本+二战(伪)+小跨吧大概
  13. UE4使用OpenCV插件调用电脑摄像头
  14. 谷歌牛逼:720p高清+长镜头,网友:对短视频行业冲击太大
  15. 插入摄像头时,系统右下角提示:无法识别的USB设备:跟这台计算机连接的一个USB设备运行不正常...
  16. mysql是怎么实现多对多的_mysql复习篇及一对多和多对多的总结(17.6.26 )
  17. tyvj P2018 「Nescafé26」小猫爬山 解题报告
  18. 想问一下杭州恒生电子证券事业部如何
  19. 精品韩国美食西餐厅介绍PPT模板
  20. 英语作文计算机国际会议开幕词,有关英语会议开场致辞范文

热门文章

  1. struct usb_hcd
  2. 搭建Nginx+Vsftp图片、视频、音频服务器
  3. Cadence Allegro PCB命令行窗口详细说明及常用命令介绍图文教程及视频演示
  4. 如何使用迅雷批量下载文件
  5. ubuntu 下图标变问号问题
  6. ASP.net MySQL ExecuteScalar的简单使用
  7. 热力图原始文本数据处理_观点丨基于百度热力图的街道活力时空分布特征分析——以江西省南昌市历史城区为例...
  8. git 回滚/撤回提交代码、误删、误提交恢复
  9. Clickhouse学习
  10. 乖离水机器人攻略_乖离性百万亚瑟王超弩级水机器人打法技巧分享