Rabbitmq的死信

摘要:
x-death是以数组的形式出现的,因为消息可能多次失效。

一、概述

死信有死信队列、死信交换器和死信消息组成。死信消息则有如下三种情况生成:

1.消费者使用basic.reject或 basic.nack并将requeue参数设置为false来拒绝该消息

2.消息设置了TTL过期时间,过期时间内没有消费导致过期

3.消息因超过队列长度导致被丢弃

如果队列删除或者队列的TTL过期时间到了被删除其中的消息是不会成为死信消息的。

每个队列可通过队列参数arg或者策略policy设置死信交换器和死信路由键来处理死信消息,当队列参数与策略都有设置时,以队列参数设置内容为准,建议使用策略。没有设置死信,消息满足死信条件将会被丢弃。

简而言之,一个队列A设置了死信交换器和路由键,当一个消息满足死信要求时会通过设置的死信交换器和路由键找到对应的队列将消息传递到对应队列B中,B也就是对应的死信队列。所以,死信交换机和死信队列都是正常的交换器和队列,和其他的交换器队列声明没区别。通过死信队列可以防止消息的意外丢失,保证重要的消息被执行记录。

二、在策略中设置死信

我们通过rabbitmqctl命令创建一个名为DLX的设置了死信交换器为my-dlx路由键为my-dlx-routekey的策略,对应用于所有的队列。

 rabbitmqctl set_policy --vhost my_vhost1 DLX ".*" '{"dead-letter-exchange":"my-dlx","dead-letter-routing-key":"my-dlx-routekey"}' --apply-to queues

或者在web管理页中添加policy如下:

Rabbitmq的死信第1张

 有多个策略的话使用优先级最高的策略,设置后队列会有个DLX的特性。

Rabbitmq的死信第2张

三、在队列参数中设置死信

我们通过队列参数设置x-dead-letter-exchange和x-dead-letter-routing-key,死信交换器必须和队列处于同一个vhost下,示例代码如下:

Dictionary<string, object> arg = new Dictionary<string, object>();
arg.Add("x-dead-letter-exchange","hello-dlx");
arg.Add("x-dead-letter-routing-key", "hello-dlx-routekey");
channel.QueueDeclare(
  "HelloQueue",//队列名称
  false,       //是否持久化
  false,       //是否只对首次声明的队列可见
  false,       //是否自动删除
  arg         ////关于队列和队列内消息的详细设置,键值对形式
);

四、死信路由

我们在上述代码中都设置了死信路由键,但是其实是可以不设置的,如果设置了就遵循设置的路由键,如果没有设置则遵循原交换器的路由键。比如:我们将消息发送到路由键为A的交换器进入队列,则当消息死信时也发送到路由键为A的死信交换器,如果设置了x-dead-letter-routing-key为B则发送到路由键为B的死信交换器中。如果不设置死信路由键,那么由CC和BCC设置的路由键也会触发,CC和BCC相当于抄送和密送到别的交换器。

如果产生死信循环,既到达同一个队列两次,消息将会被抛弃。当死信消息发送到死信队列后将会从原队列删除,避免过多消息的积压,但是如果目标的死信队列不能接受消息,则该死信消息将可能丢失。

五、死信消息

当死信消息被发送到死信队列后会有以下变化:

1.消息的交换器名称会改为死信交换器名称;

2.设置了死信路由键的话,路由键会相应更改;

3.CC和BCC标头将会删除;

死信消息将会添加一些标头,我们先看下打印的标头:

{"Headers":{
        "x-death":[
            {
                "count":1,
                "reason":"ZXhwaXJlZA==",
                "queue":"SGVsbG9RdWV1ZQ==",
                "time":{
                    "UnixTime":1637409202
                },
                "exchange":"SGVsbG9FeGNoYW5nZQ==",
                "routing-keys":[
                    "aG9sYQ=="
                ]
            }
        ],
        "x-first-death-exchange":"SGVsbG9FeGNoYW5nZQ==",
        "x-first-death-queue":"SGVsbG9RdWV1ZQ==",
        "x-first-death-reason":"ZXhwaXJlZA=="
    }
}

可以看到值是Base64格式的,新添加了x-death、x-first-death-exchange、x-first-death-queue、x-first-death-reason四个值。

x-first-death-exchange:第一次的成为死信时的交换器名称;

x-first-death-queue:第一次的成为死信时的队列名称;

x-first-death-reason:第一次的成为死信时的原因,死亡原因分为四种下同分别是:rejected(消息处理被拒绝)、expired (ttl时间到期)、maxlen(超过队列允许最大长度)和Delivery-limit(消息返回的次数超限额)

这三个是第一次死信的时候添加的,后面就不会变了。

x-death里面是数组形式的,因为消息可能多次死信。新条目被添加到x-death 数组的开头如果x-death已经包含一个具有相同队列和死字原因的条目,它的计数字段count将增加,并将移到数组的开头。

queue:消息在死信之前所在队列的名称;

reason:死信的原因,同上;

time:消息被死信的日期和时间,为 64 位 AMQP 0-9-1 时间戳;

exchange :消息发布到的交换器名(请注意,如果消息多次死信,这将是死信交换);

routing-keys :消息发布时使用的路由键(包括CC密钥,但不包括BCC密钥 );

count : 由于这个原因,这条消息在这个队列中被死信多少次;

original-expiration(如果消息由于消息的TTL死信的):消息的原始到期属性。该到期属性从死刻字的消息,以防止它被路由到任何队列再次到期删除。

学习链接:https://www.rabbitmq.com/dlx.html

免责声明:文章转载自《Rabbitmq的死信》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SAP MM UB类型的退货STO流程简述CSS3自定义滚动条样式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用ionic3快速开发webapp(二)

本文整理了使用ionic3开发时会用到的一些最基本组件及用法 1、ion-tabs 最常见的通过标签切换页面: tabs.html 1 <ion-tabs> 2 <ion-tab [root]="tab1Root" tabTitle="首页" tabIcon="home"></ion-tab> 3 <ion...

【Visual C++】游戏开发笔记十三 游戏输入消息处理(二) 鼠标消息处理

上一节我们讲解了键盘消息处理相关的知识。键盘加鼠标作为目前人机交互方式依旧的主流,在讲完键盘消息处理之后接着讲鼠标消息处理,自然是理所当然的。 这一节主要介绍各种鼠标消息的处理方式以及一些相关函数的运用方法,然后用一个小实例来巩固本节所学。 一,鼠标消息的处理方式 大家都知道,目前市场上主流鼠标规格为两个按键加上一个滚轮。那么,我们先列出Windo...

XMPP协议的原理介绍

XMPP(可扩展消息处理现场协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线现场探測。它在促进server之间的准即时操作。这个协议可能终于同意因特网用户向因特网上的其它不论什么人发送即时消息,即使其操作系统和浏览器不同。 XMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。XMPP眼下被IETF国际标准组织完...

golang-nsq高性能消息队列

前言 tips:如果本文对你有用,请爱心点个赞,提高排名,让这篇文章帮助更多的人。谢谢大家!比心❤~ 如果解决不了,可以在文末加我微信,进群交流。 NSQ 是实时的分布式消息处理平台,其设计的目的是用来大规模地处理每天数以十亿计级别的消息。 NSQ 具有分布式和去中心化拓扑结构,该结构具有无单点故障、故障容错、高可用性以及能够保证消息的可靠传递的特征。 N...

Java算法-hash算法

Hash ,一般翻译做“ 散列” ,也有直接音译为“ 哈希” 的,就是把任意长度的输入(又叫做预映射, pre-image ),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不 同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到...

Mininet实验 多个数据中心的拓扑网络实现

实验目的 掌握多数据中心网络拓扑的构建 掌握多数据中心数据交换过程 实验原理 主机间发送消息上报给交换机,交换机对收到的报文信息进行分析判断,如果交换机中存在此消息相对应的流表,则交换机直接下发流表,将报文消息转发给目的主机;如果交换机中没有相对应的流表,交换机将此发送消息给控制器,控制器根据消息分析关键字段内容,进行流表下发决策,交换机再将消息发送...