DLX,全称为Dead-letter-Exchange,被称为死信交换机(死信邮箱)。如果消息在队列中编程死信(dead-message)之后,可以被重新发送到另一个交换机中,这个交换机就是DLX,死信队列就是绑定DLX的队列。
消息死信原因:
消息被拒绝
消息过期(前面讲解过)
队列达到最大长度
DLX和正常交换机没有区别,可以在任何队列上被指定(设置某个队列的属性)。当这个队列中存在死信时,RabbitMQ就会自动将消息设置到DLX中,然后被路由到另一个队列,即死信队列。
消费死信队列逻辑图
在spring/spring-rabbitmq.xml文件,添加如下内容:
? ? ? ? ? ? ? ? ? ?
增加测试消息(过期和队列达到最大长度),过期的和超过长度的消息将会被投递到死信交换机上,添加如下内容:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
在ProducerTest.java类增加如下方法:
/**??*??*?功能描述:?过期后的消息投递到死信队列??*?消息将会被投递到正常的队列,该队列有设置过期时间,过期后消息会被投递到死信交换机(队列)??*/@Testpublic?void?messageDxlTtlTest(){???rabbitTemplate.convertAndSend("wx_normal_exchange",???????"wx_ttl_dlx",???????"测试过期后的消息投递到死信交换机,有效时间10s");}
第一步:生产者将“测试过期后的消息投递到死信交换机,有效时间10s”的消息投递到名称为wx_normal_exchange的交换机,路由key为wx_ttl_dlx?。
第二步:wx_ttl_dlx路由key绑定到wx_ttl_dlx_queue队列中。
第三步:设置wx_ttl_dlx_queue的超时时间为10s,超时后消息将被投递到wx_dlx_exchange死信交换机中。
第四步:设置wx_dlx_exchange死信交换机的路由key为wx_ttl_dlx(和生产者投递消息的路由key保持一致)
第五步:将wx_dlx_exchange死信队列设置的wx_ttl_dlx路由key绑定到wx_dlx_queue死信队列中。
TPS:由上述可知一条消息在未被消费的情况下,先被投递到wx_ttl_dlx_queue 队列中,经过10s超时后会再被投递到wx_ttl_dlx死信队列。
登录RabbitMQ管理端,未过期消息如下所示:
可以看到新建wx_ttl_dlx_queue?和wx_dlx_queue两个队列,其中wx_ttl_dlx_queue队列有TTL和DLX标记,并且产生了1条数据,和我们预期相符。
10s后超时信息如下所示:
wx_dlx_queue?死信队列增加了一条消息。
在ProducerTest.java类增加如下方法:
/**??*??*?功能描述:?超过长度的消息投递到死信队列??*?消息将会被投递到正常的队列,该队列有设置最大长度为2,超过最大长度则最早的消息被投递到死信交换机(队列)??*/@Testpublic?void?maxMessageDxlTest(){????rabbitTemplate.convertAndSend("wx_normal_exchange",????????????????"wx_max_dlx",????????????????"消息1:测试超过长度后的消息投递到死信交换机,最大长度为2");????rabbitTemplate.convertAndSend("wx_normal_exchange",????????????????"wx_max_dlx",????????????????"消息2:测试超过长度后的消息投递到死信交换机,最大长度为2");????rabbitTemplate.convertAndSend("wx_normal_exchange",????????????????"wx_max_dlx",????????????????"消息3:测试超过长度后的消息投递到死信交换机,最大长度为2");}
第一步:生产者将3个“消息x:测试超过长度后的消息投递到死信交换机,最大长度为2”的消息投递到名称为wx_normal_exchange的交换机,路由key为wx_max_dlx?。
第二步:wx_max_dlx路由key绑定到wx_max_dlx_queue队列中。
第三步:设置wx_max_dlx_queue的最大长度为2,超过最大长度后会将最早发送的消息投递到wx_dlx_exchange死信交换机中。
第四步:设置wx_dlx_exchange死信交换机的路由key为wx_max_dlx(和生产者投递消息的路由key保持一致)
第五步:将wx_dlx_exchange死信队列设置的wx_max_dlx路由key绑定到wx_dlx_queue死信队列中。
TPS:消息过长的投递遵循先进先出规则,即1、2、3依次投递至队列中,设置最大长度为2,那么第3条投递后,会将第1条消息放至死信队列
执行上述测试代码,打开RabbitMQ管理页面,如下图所示:
被投递到死信队列的消息1
依然保留在队列中的消息2和消息3
MQ自动创建了有Lim和DLX标记的wx_max_dlx_queue队列,测试代码中我们写入了3条消息,由于设置最大长度为2,那么wx_max_dlx_queue队列永远会保持最大2条消息,那么最先投递的消息放到了wx_dlx_queue死信队列中。
原文:https://blog.51cto.com/u_7117633/2867698