参考文献:https://www.rabbitmq.com/dlx.html

死信,顾名思义,就是死掉的消息,死掉的消息是会被一般的队列丢弃的。如果这些消息很重要,而我们又需要,怎么办?凡事都有一个退路,现在就有一种方法可将这些死信消息存下来,那就是DLX(Dead Letter Exchanges)。DLX是专门用来存储死信消息到指定队列中的一种交换机。需要在声明队列时指定DLX和死信存放队列的路由Key,因为RabbitMQ是通过Exchange去匹配路由key寻找队列的。

死信消息是怎么产生的呢?

1、消息被拒(basic.reject or basic.nack)并且没有重新入队(requeue=false);

2、消息在队列中过期,即当前消息在队列中的存活时间已经超过了预先设置的TTL(Time To Live)时间;

3、当前队列中的消息数量已经超过最大长度。

消息进入死信队列的过程:消息 -> 队列 (触发以上条件)-> DLX交换机 -> DLK队列

以上是对死信及其去向的介绍,接下来上代码!

var factory = new ConnectionFactory() { HostName = "localhost",UserName="ty2017",Password="123456",VirtualHost="log" };

using (var connection = factory.CreateConnection()) {

using (var channel = connection.CreateModel()) {

//声明一个direct类型的交换机,用来当做某个队列的死信交换机(DLX)

channel.ExchangeDeclare("e.log.dead", //交换机名称

"direct"); //交换机类型

//声明一个队列,用来存放死信消息

channel.QueueDeclare(queue: "q.log.dead",

durable: false,

exclusive: false,

autoDelete: false,

arguments: null);

//声明一个队列,并指定该队列的DLX和死信路由key,且还需要设置TTL(消息存活时间)

channel.QueueDeclare(queue: "q.log.error",

durable: false,

exclusive: false,

autoDelete: false,

arguments: new Dictionary {

{ "x-dead-letter-exchange","e.log.dead"}, //设置当前队列的DLX

{ "x-dead-letter-routing-key","dead"}, //设置DLX的路由key,DLX会根据该值去找到死信消息存放的队列

{ "x-message-ttl",10000} //设置消息的存活时间,即过期时间

});

//将DLX和死信存放队列绑定,并产生一个路由key

channel.QueueBind("q.log.dead", "e.log.dead", "dead");

//绑定消息队列

channel.QueueBind("q.log.error", //队列名称

"e.log", //交换机名称

"log.error"); //自定义的RoutingKey

//需要发送的消息

var body = Encoding.UTF8.GetBytes(param.Data);

var properties = channel.CreateBasicProperties();

//设置消息持久化

properties.SetPersistent(true);

//发布消息

channel.BasicPublish(exchange: "e.log",

routingKey: "log.error",

basicProperties: properties,

body: body);

}

}

解释一下代码:

1.有一个名为q.log.error的消息队列,该队列中消息的过期时间为10000毫秒;

2.有一个名为e.log.dead的交换机(Exchange),其类型是direct;

3.有一个名为q.log.dead的消息队列,等会我们会将死信消息存入该队列中;

4.将e.log.dead交换机和q.log.dead队列绑定,并产生一个名为dead的RoutingKey;

5.指定e.log.dead交换机为队列q.log.error的DLX(死信交换机);

6.指定dead为DLX的RoutingKey;

7.如果q.log.error队列中产生了死信,RabbitMQ则会将死信消息发送给e.log.dead交换机,该交换机再通过dead(设置的DLX的RoutingKey)去找到q.log.dead队列,并将该死信消息存放进去。

其实DLX是一个普通的交换机,只是我们在声明队列的时候,将其指定为该队列的死信交换机(x-dead-letter-exchange)而已,也就是死信消息的去处。有交换机就需要有一个RoutingKey,因此,我们在设置DLX的时候,也需要一并设置x-dead-letter-routing-key参数。

让我们看一下web管理工具中的情况:

消息进入死信队列的过程:消息 -> q.log.error队列 (过期TTL)-> e.log.dead交换机DLX (通过DLK) -> q.log.dead队列

将q.log.dead队列绑定到e.log.dead交换机

在web管理工具中创建q.log.error队列时设置属性 :

x-message-ttl(消息超时时间TTL)

x-dead-letter-exchange=e.log.dead(对应死信交换机DXL)

x-dead-letter-routing-key=q.log.dead(进入死信交换机后的路由键,即死信最终路由到的队列DLK)

消息过期之前,消息保留在q.log.error队列中。TTL表示当前队列设置了消息过期时间,DLX表示当前队列设置了死信交换机,DLK表示当前队列设置了死信交换机对应的RoutingKey(消息发到死信交换机后,路由到哪个queue中)。具体信息如下图所示:

消息过期之后就变为了死信消息,消息就通过e.log.dead交换机跑到了q.log.dead队列中。如下图所示:

web管理工具中测试发送接收

发送:

Exchange页面点击相应的交换机,进入交换机信息页面,找到 Publish message,设置 路由键+内容(Payload)发送消息进入此交换机

接收:

Queues页面点击路由键对应的接收队列(先绑定交换机),进入队列信息页面,找到 Get messages,设置ack模式点击Get message,显示接收的消息内容(四种ack模式依次:Nack+重新入队;ACK;拒绝+重新入队;拒绝+不重新入队)

重新入队会放回队列首,需要谨慎避免无法消费造成死循环

php mq死信队列,RabbitMQ死信队列+延时队列相关推荐

  1. RabbitMQ介绍与延时队列

    RabbitMQ特性 消息可靠性:典型的生产者-消费者模型,发送端有消息发送确认机制,服务端有消息持久化方案,消费端有消息Ack机制 灵活的消息路由分发:多种多样的交换机 多语言客户端开发AMQP:只 ...

  2. (转) RabbitMQ学习之延时队列

    http://blog.csdn.net/zhu_tianwei/article/details/53563311 在实际的业务中我们会遇见生产者产生的消息,不立即消费,而是延时一段时间在消费.Rab ...

  3. Docker安装RabbitMQ并安装延时队列插件

    一.RabbitMQ简介 RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消 ...

  4. 阻塞队列之七:DelayQueue延时队列

    一.DelayQueue简介 是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的(PriorityQueue实际 ...

  5. springboot集成rabbitmq死信队列的延时队列使用

    目录         1.自动分列延时队列 2.应答失败自动转储延时再通知机制 ------------------------------------------------------------ ...

  6. Rabbitmq死信队列

    目录 1.什么是死信队列 2.产生死信队列的原因 3.代码实现---直连交换机 3.1.导入依赖 3.2.配置rabbitmq连接信息 3.3.编写配置类 3.4.编写生产者 3.5.编写消费者 3. ...

  7. RabbitMQ死信队列应用

    目录 1.什么是死信队列 2.死信队列应用场景 3.延迟消息概念 3.1 消息的TTL(Time To Live) 3.2 死信交换器 3.3 延时队列 4.死信队列使用流程图 5.死信队列应用(管理 ...

  8. 【SpringBoot】43、SpringBoot中整合RabbitMQ实现延时队列(延时插件篇)

    死信队列实现篇,参考文章:[SpringBoot]60.SpringBoot中整合RabbitMQ实现延时队列(死信队列篇) 一.介绍 1.什么是延时队列? 延时队列即就是放置在该队列里面的消息是不需 ...

  9. RabbitMQ真延时队列实现消息提醒功能

    RabbitMQ真延时队列实现消息提醒功能 一.需求场景 用户可以制定多个计划,同时可给该计划设置是否需要到点提醒,且中途可以取消提醒或修改提醒时间. 二.需要解决的问题 学习过rabbitmq的同学 ...

最新文章

  1. 【收藏】银联在线支付商户UPMP接口的使用和说明
  2. LilyPad Arduino可穿戴技术和电子织物控制器板简介
  3. Windows XP安装Python,最高支持到3.4.4,后续版本不支持
  4. 基于Angularjs实现分页
  5. 12、OpenCV Python 图像梯度
  6. 区分错误类型_牛鹭学院:Bug类型解析及其常见实例介绍
  7. 在html表格中怎么创建下拉列表,在html网页中如何做个下拉列表?下拉列表的方法有哪几种?...
  8. 显卡参数详解[原创]
  9. 国外的英文JAVA论坛
  10. freebase api的使用
  11. android系统一直显示通知栏_Android通知栏详解
  12. php操作redis命令
  13. 计算机科学与技术以为舟,于哲舟-吉林大学计算机科学与技术学院
  14. 使用HBuilder制作一个简单的HTML5动漫网页——小林家的龙女仆 HTML+CSS学生个人网页制作 学生静态HTML网页源码 dreamweaver网页作业 简单网页课程成品
  15. 安装rabbitMQ踩的坑
  16. 以太坊:Web3.js 0.20 使用说明
  17. python3攻击服务器_Python服务器用套接字互相攻击
  18. 什么是MBS和ABS(资产支撑证券化)
  19. c++国密算法SM2加密解密demo
  20. c语言错误1004,Excel VBA运行时错误1004仅以名称以'c'开头

热门文章

  1. 大学生计算机二级office备考指南
  2. 利用JMeter批量注册用户
  3. 应用之星:新版本上线有礼 大家一起来“找茬”
  4. (NLP) 淘宝评论处理(1)--工具库介绍
  5. 寄存器>缓存>内存>硬盘
  6. 看看别人后端API接口性能优化的11个方法,那叫一个优雅
  7. Natural Language Processing(一)
  8. 欧洲海运专线:欧洲海运专线需要多久时间到达
  9. 第十七期 U-Boot norflash 操作原理分析 《路由器就是开发板》
  10. HTML5 LocalStorage 本地存储原理详解