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

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

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

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

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

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

            var factory = new ConnectionFactory() { HostName = "localhost",UserName="ty2017",Password="",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<string, object> {
{ "x-dead-letter-exchange","e.log.dead"}, //设置当前队列的DLX
{ "x-dead-letter-routing-key","dead"}, //设置DLX的路由key,DLX会根据该值去找到死信消息存放的队列
{ "x-message-ttl",} //设置消息的存活时间,即过期时间
}); //将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队列中。DLX表示当前队列设置了死信交换机,DLK表示当前队列设置了死信交换机对应的RoutingKey,TTL表示当前队列设置了消息过期时间。具体信息如下图所示:

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

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

RabbitMQ Dead Lettering(死信)的更多相关文章

  1. 关于 RabbitMQ 的 Dead-Letters-Queue “死信队列”

      来自一个队列的消息可以被当做‘死信’,即被重新发布到另外一个“exchange”去,这样的情况有: 消息被拒绝 (basic.reject or basic.nack) 且带 requeue=fa ...

  2. RabbitMQ (五):死信队列

    什么是TTL RabbitMQ的TTL全称为Time-To-Live,表示的是消息的有效期.消息如果在队列中一直没有被消费并且存在时间超过了TTL,消息就会变成了"死信" (Dea ...

  3. Rabbitmq消费失败死信队列

    Rabbitmq 重消费处理 一 处理流程图: 业务交换机:正常接收发送者,发送过来的消息,交换机类型topic AE交换机: 当业务交换机无法根据指定的routingkey去路由到队列的时候,会全部 ...

  4. RabbitMQ TTL、死信队列

    TTL概念 TTL是Time To Live的缩写,也就是生存时间. RabbitMQ支持消息的过期时间,在消息发送时可以进行指定. RabbitMQ支持队列的过期时间,从消息入队列开始计算,只要超过 ...

  5. SpringBoot整合RabbitMQ实战附加死信交换机

    前言 使用springboot,实现以下功能,有两个队列1.2,往里面发送消息,如果处理失败发生异常,可以重试3次,重试3次均失败,那么就将消息发送到死信队列进行统一处理,例如记录数据库.报警等 环境 ...

  6. 【RabbitMQ】一文带你搞定RabbitMQ死信队列

    本文口味:爆炒鱿鱼   预计阅读:15分钟 一.说明 RabbitMQ是流行的开源消息队列系统,使用erlang语言开发,由于其社区活跃度高,维护更新较快,性能稳定,深得很多企业的欢心(当然,也包括我 ...

  7. rabbitmq死信队列消息监听

    #邮件通知并发送队列消息#!/bin/bash maillog="/var/log/mq.maillog" message_file="/tmp/mq_message&q ...

  8. 【MQ中间件】RabbitMQ -- RabbitMQ死信队列及内存监控(4)

    1.RabbitMQ TTL及死信队列 1.1.TTL概述 过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取:过了之后消息将自动被删除.RabbitMQ可以对消息和队列设 ...

  9. RabbitMQ死信队列

    关于RabbitMQ死信队列 死信队列 听上去像 消息“死”了     其实也有点这个意思,死信队列  是 当消息在一个队列 因为下列原因: 消息被拒绝(basic.reject/ basic.nac ...

随机推荐

  1. Codeforces 985 D - Sand Fortress

    D - Sand Fortress 思路: 二分 有以下两种构造, 分别二分取个最小. 代码: #include<bits/stdc++.h> using namespace std; # ...

  2. Windows 下 Redis 服务无法启动,错误 1067 进程意外终止解决方案

    1.检查端口是否被占用 2.修改 Windows 服务里的 Redis 服务为本地系统服务(修改方式见下文) 方法: 1.看系统日志 桌面计算机/此电脑(Win10名称)右键打开管理,或 Win+R ...

  3. layui 日期插件onchange事件失效的方法

    laydate.render({ elem:'#text1',//制定元素 type:'date', //range:true,//开启左右面板 min:'2017-09-1',// max:'201 ...

  4. (转)3个常用基于Linux系统命令行WEB网站浏览工具(w3m/Links/Lynx)

    一般我们常用的浏览器肯定是基于可视化界面的图文结合的浏览界面效果,比如FireFox.Chrome.Opera等等,但是有些时候折腾和项目 的需要,在Linux环境中需要查看某个页面的文字字符,我们需 ...

  5. android -------- 蓝牙Bluetooth

    什么是蓝牙? 也可以说是蓝牙技术.所谓蓝牙(Bluetooth)技术,实际上是一种短距离无线电技术,是由爱立信公司公司发明的.利用“蓝牙”技术,能够有效地简化掌上电脑.笔记本电脑和移动电话手机等移动通 ...

  6. 遍历input文本框

    最近写的一个项目中,页面中有很多的“text文本框”和“select下拉框” 校验input框和select框是否非空,如果为空给出提示.反之,隐藏提示内容. html  页面中的input类型有ty ...

  7. prometheus远程连接m3db实现存储

    如果是prometheus server配置文件添加如下: remote_read: - url: "http://m3coordinator.m3db.svc.cluster.local: ...

  8. virtualbox不能安装64位操作系统

    现在virtualbox 还是比较好用的虚拟机.新建立一个不同的操作系统还是非常方便. virtualbox下载地址  https://www.virtualbox.org/wiki/Download ...

  9. 数据结构与算法之PHP查找算法(顺序查找)

    对于查找数据来说,最简单的方法就是从列表的第一个元素开始对列表元素逐个进行判断,直到找到了想要的结果,或者直到列表结尾也没有找到,这种方法称为顺序查找. 一.基本写法 顺序查找的实现很简单.只要从列表 ...

  10. 时间序列(六): 炙手可热的RNN: LSTM

    目录 炙手可热的LSTM 引言 RNN的问题 恐怖的指数函数 梯度消失* 解决方案 LSTM 设计初衷 LSTM原理 门限控制* LSTM 的 BPTT 参考文献: 炙手可热的LSTM 引言 上一讲说 ...