RabbitMQ之死信队列
2017-02-08 20:46
567 查看
DLX, Dead-Letter-Exchange。利用DLX, 当消息在一个队列中变成死信(dead message)之后,它能被重新publish到另一个Exchange,这个Exchange就是DLX。消息变成死信一向有一下几种情况:
消息被拒绝(basic.reject/ basic.nack)并且requeue=false
消息TTL过期(参考:RabbitMQ之TTL(Time-To-Live 过期时间))
队列达到最大长度
DLX也是一个正常的Exchange,和一般的Exchange没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性,当这个队列中有死信时,RabbitMQ就会自动的将这个消息重新发布到设置的Exchange上去,进而被路由到另一个队列,可以监听这个队列中消息做相应的处理,这个特性可以弥补RabbitMQ 3.0以前支持的immediate参数(可以参考RabbitMQ之mandatory和immediate)的功能。
核心代码实现:通过在queueDeclare方法中加入“x-dead-letter-exchange”实现。
你也可以为这个DLX指定routing key,如果没有特殊指定,则使用原队列的routing key
还可以使用policy来配置:
修改RabbitMQ之TTL(Time-To-Live 过期时间)中的例子:
通过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
RabbitMQ之mandatory和immediate
RabbitMQ(四)RabbitMQ死信邮箱(DLX)
RabbitMQ Dead Letter Exchanges
欢迎支持《RabbitMQ实战指南》以及关注微信公众号:朱小厮的博客。
消息被拒绝(basic.reject/ basic.nack)并且requeue=false
消息TTL过期(参考:RabbitMQ之TTL(Time-To-Live 过期时间))
队列达到最大长度
DLX也是一个正常的Exchange,和一般的Exchange没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性,当这个队列中有死信时,RabbitMQ就会自动的将这个消息重新发布到设置的Exchange上去,进而被路由到另一个队列,可以监听这个队列中消息做相应的处理,这个特性可以弥补RabbitMQ 3.0以前支持的immediate参数(可以参考RabbitMQ之mandatory和immediate)的功能。
核心代码实现:通过在queueDeclare方法中加入“x-dead-letter-exchange”实现。
channel.exchangeDeclare("some.exchange.name", "direct"); Map<String, Object> args = new HashMap<String, Object>(); 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
修改RabbitMQ之TTL(Time-To-Live 过期时间)中的例子:
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<String, Object> argss = new HashMap<String, Object>(); 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
参考资料
RabbitMQ之TTL(Time-To-Live 过期时间)RabbitMQ之mandatory和immediate
RabbitMQ(四)RabbitMQ死信邮箱(DLX)
RabbitMQ Dead Letter Exchanges
欢迎支持《RabbitMQ实战指南》以及关注微信公众号:朱小厮的博客。
相关文章推荐
- Rabbitmq消费失败死信队列
- RabbitMQ 死信/死信队列
- rabbitmq AMQP 死信队列报错COMMAND_INVALID,PRECONDITION_FAILED
- rabbitmq 死信队列的使用方式
- Rabbitmq消费失败死信队列
- RabbitMQ(六)使用Dead Letter(死信队列)进行延时发送
- RabbitMQ 死信/死信队列
- 【RabbitMQ】——5种队列(转)
- 如何基于RabbitMQ实现优先级队列
- RabbitMQ消息队列基础概念详细讲解
- C#.NET使用消息队列RabbitMQ
- python【第十一篇】消息队列RabbitMQ、缓存数据库Redis
- RabbitMQ:伪延时队列
- RabbitMQ(消息队列)安装、集群
- rabbitmq 消息队列工作模式
- RabbitMQ消息队列(九):Publisher的消息确认机制
- PHP消息队列rabbitmq——windows
- RabbitMQ消息队列(一): Detailed Introduction 详细介绍(转)
- 快速入门分布式消息队列之 RabbitMQ(2)
- RabbitMQ消息队列(一基本概念和常用命令)