RabbitMq 之死信队列-神之有用*2

DLX ,全称为 Dead-Letter-Exchange ,可以称之为死信交换器,也有人称之为死信邮箱。当 消息在一个队列中变成死信 (dead message) 之后,它能被重新被发送到另一个交换器中,这个交换器就是 DLX ,绑定 DLX 的队列就称之为死信队列。

消息变成死信 ,一般是由于以下几种情况:
~消息被拒绝 (Basic.Reject/Basic .Nack) ,井且设置 requeue 参数为 false;
~消息过期;
~队列达到最大长度。

DLX 也是一个正常的交换器,和一般的交换器没有区别,它能在任何的队列上被指定 ,实际上就是设置某个队列的属性。当这个队列中存在死信时,RabbitMQ 就会自动地将这个消息 新发布到设置的 DLX上去 ,进而被路由到另一个队列,即死信队列。可以监听这个队列中的消 息、以进行相应的处理,这个特性与将消息的 TTL 设置为0 配合使用可以弥补 imrnediate 参数 的功能。

通过在 channel.queueDeclare 方法中设置 x-dead-letter-exchange 参数来为这 个队列添加 DLX

channel.exchangeDeclare("dlx_exchange " , "direct "); // 创建 DLX: dlx_exchange 
Map args = new HashMap(); 
args.put("x-dead-letter-exchange" , " dlx_exchange "); // 值为交换机的名字
//为队列 myqueue 添加 DLX
channel.queueDeclare("myqueue" , false , false , false , args); 
//也可以为这个 DLX 指定路由键,如果没有特殊指定,则使用原队列的路由键:
args.put("x-dead-letter-routing-key" , "dlx-routing-key");// 

示例:

channel.exchangeDeclare("exchange.dlx" , "direct " , true); 
channel.exchangeDeclare( "exchange.normal " , " fanout " , true);  
Map args = new HashMap();
args.put("x-message-ttl " , 10000);
args.put( "x-dead-letter-exchange " , " exchange.dlx"); 
args.put( "x-dead-letter-routing-key" , " routingkey");
channel.queueDeclare( "queue.normal" , true , false , false , args);  
channel.queueBind( "queue.normal " , "exchange .normal" , ""); 
channel.queueDeclare( "queue.dlx" , true , false , false , null) ; 
channel.queueBind( "queue.dlx" , "exchange.dlx " , routingkey"); 
channel.basicPublish("exchange.normal","rk",MessageProperties.PERSISTENT_TEXT_PLAIN,"dlx".getBytes());

这里创建了两个交换器 exchange.normal 和 exchange.dlx 分别绑定两个队列 queue.normal 和 queue.dlx。

生产者首先发送一条携带路由键为 rk 的消息,然后经过交换器 exchange.normal 顺利地存储到队列 queue.normal 中。由于队列 queue.normal 设置了过期时间为 10s 在这 10s 内没有消费者消费这条消息,那么判定这条消息为过期。由于设置了 DLX 过期 之时 消息被丢给交换器 exchange.dlx 中,这时找到 与exchange.dlx 匹配的队列 queue.dlx 最后消息被存储在 queue.dlx 这个死信队列中。


来自RabbitMq实战.pdf

对于 RabbitMQ 来说, DLX 是一个非常有用的特性 它可以处理异常情况下,消息不能够 被消费者正确消费(消费者调用了 Basic.Nack 或者 Basic.Reject) 而被置入死信队列中 的情况,后续分析程序可以通过消费这个死信队列中的内容来分析当时所遇到的异常情况,进 而可以改善和优化系统。 DLX 配合 TTL 使用还可以实现延迟队列的功能。

你可能感兴趣的:(RabbitMq 之死信队列-神之有用*2)