博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RabbitMQ之死信队列
阅读量:6845 次
发布时间:2019-06-26

本文共 2496 字,大约阅读时间需要 8 分钟。

DLX, Dead-Letter-Exchange。利用DLX, 当消息在一个队列中变成死信(dead message)之后,它能被重新publish到另一个Exchange,这个Exchange就是DLX。消息变成死信一向有一下几种情况:

  • 消息被拒绝(basic.reject/ basic.nack)并且requeue=false
  • 消息TTL过期(参考:)
  • 队列达到最大长度

DLX也是一个正常的Exchange,和一般的Exchange没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性,当这个队列中有死信时,RabbitMQ就会自动的将这个消息重新发布到设置的Exchange上去,进而被路由到另一个队列,可以监听这个队列中消息做相应的处理,这个特性可以弥补RabbitMQ 3.0以前支持的immediate参数(可以参考)的功能。

核心代码实现:通过在queueDeclare方法中加入“x-dead-letter-exchange”实现。

channel.exchangeDeclare("some.exchange.name", "direct");Map
args = new HashMap
();args.put("x-dead-letter-exchange", "some.exchange.name");channel.queueDeclare("myqueue", false, false, false, args);

你也可以为这个DLX指定routing key,如果没有特殊指定,则使用原队列的routing key

args.put("x-dead-letter-routing-key", "some-routing-key");

还可以使用policy来配置:

rabbitmqctl set_policy DLX ".*" '{
"dead-letter-exchange":"my-dlx"}' --apply-to queues

修改中的例子:

public static void createQueue(){    try {        ConnectionFactory factory = new ConnectionFactory();        factory.setHost(ip);        factory.setPort(port);        factory.setUsername(username);        factory.setPassword(password);        Connection connection = factory.newConnection();        Channel channel = connection.createChannel();        Map
argss = new HashMap
(); argss.put("vhost", "/"); argss.put("username","root"); argss.put("password", "root"); argss.put("x-message-ttl",6000); argss.put("x-dead-letter-exchange","exchange.dlx.test"); argss.put("x-dead-letter-routing-key","queue.dlx.test"); channel.queueDeclare("queue.dlx.test", durable, exclusive, autoDelete, argss); } catch (IOException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); }}

通过RabbitMQ的管理界面可以看到:

这里写图片描述
queue.dlx.test这个queue中有个“DLX”和“DLK”的标记. DLX关联的是exchangeName, DLK关联的是routingKey.

详细说明:

在RabbitMQ中有两个exchange: exchange.dlx.self和exchange.dlx.test,两个queue:queue.dlx.test和%DLX%queue.dlx.test
exchange.dlx.self是正常情况下,生产者发送消息到此exchange中,绑定关系如图:
这里写图片描述
exchang.dlx.test是产生死信之后,原queue[queue.dlx.test]的死信发送到此exchange中,绑定关系如图:
这里写图片描述

数据首先发送到 exchange[exchange.dlx.self],根据routingkey[dlx]路由到queue.dlx.test,如果正常情况下,消费者可以消费queue.dlx.test的内容。但是如果queue.dlx.test中有消息变成了dead message即死信了,那么这个死信则会通过exchangeName=exchange.dlx.test, routingKey=”queue.dlx.test”路由到死信队列%DLX%queue.dlx.test中,如果要消费这个dead message, 此时消费者必须消费%DLX%queue.dlx.test中的内容而不是queue.dlx.test中的内容。

如果不指定x-dead-letter-routing-key参数,则使用原来的routingkey


参考资料

你可能感兴趣的文章
TortoiseSVN客户端重新设置用户名和密码
查看>>
Android -- 获取汉字的首字母
查看>>
nutch搏斗之一
查看>>
MySQL -- 全文检索(布尔全文检索)
查看>>
OAF SubTabLayoutBean隐藏子控件
查看>>
webpack CommonsChunkPlugin详细教程
查看>>
Java RSA 加密 解密 签名 验签
查看>>
printFinal用法示例
查看>>
ELK系列~Nxlog日志收集加转发(解决log4日志换行导致json转换失败问题)
查看>>
git命令合并分支代码
查看>>
cookie和session
查看>>
cmd批处理中set /a和set /p的区别介绍
查看>>
Forms authentication timeout vs sessionState timeout
查看>>
C++虚函数表分析
查看>>
如何理解“哲学家们只是用不同的方式解释世界,而问题在于改变世界”?
查看>>
逗号只能存在于数字中间
查看>>
.NET平台微服务项目汇集
查看>>
Dubbo-admin管理平台的安装
查看>>
DDD中的值对象如何用NHibernate进行映射
查看>>
【设计】概要设计-详细设计-到底需要输出什么???
查看>>