zoukankan      html  css  js  c++  java
  • rabbitMq 学习笔记(二) 备份交换器,过期时间,死信队列,死信队列

    备份交换器

      备份交换器,英文名称为 Altemate Exchange,简称庙,或者更直白地称之为"备胎交换器"。 生产者在发送消息的时候如果不设置 mandatory 参数, 那么消息在未被路由的情况下将会丢失: 如果设置了 mandatory 参数,那么需要添加 ReturnListener 的编程逻辑,生产者的代码将变得复杂。如果既不想复杂化生产者的编程逻辑,又不想消息丢失,那么可以使用备份交换器, 这样可以将未被路由的消息存储在 RabbitMQ 中,再在需要的时候去处理这些消息。

      代码如下:

    1 channel.ExchangeDeclare("myAe", "fanout", true, false, null); //声明备份交换器
    2 Dictionary<string, object> arg = new Dictionary<string, object>();
    3 arg.Add("a1ternate-exchange", "myAe");
    4 channel.ExchangeDeclare("ExchangeName", "direct", true, false, arg); //声明交换器与备份交换器绑定
    5 channel.QueueDeclare("QueueName", true, false, false, null);
    6 channel.QueueDeclare("QueueAe", true, false, false, null); //备份队列
    7 channel.QueueBind("QueueName", "ExchangeName", "RoutingKey", null);
    8 channel.QueueBind("QueueAe", "myAe", "");
    9 channel.BasicPublish("ExchangeName", "RoutingKey",null, Encoding.UTF8.GetBytes("helloword"));

    当消息的 RoutingKey 不是 “RoutingKey”时,消息将不能被正确路由到“ExchangeName”上的队列,此时就会发送给 myAe 交换器,进而发送到 QueueAe这个队列 。

    考虑到备份交换器的作用,建议将交换器类型设置为fanout,因为消息被重新发送到 备份交换器时的路由键和从生产者发出的路由键是一样的。

    过期时间(TTL)

       RabbitMQ 可以对"消息"和"队列"设置 TTL。

      目前有两种方法可以设置消息的 TTL。第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。第二种方法是对消息本身进行单独设置,每条消息的TTL可以不同。如果两种方法一起使用,则消息的 TTL 以两者之间较小的那个数值为准。消息在队列中的生存时间一旦超过设置的 TTL 值时,就会变成"死信" (Dead Message),消费者将无法再收到该消息。

    1 channel.ExchangeDeclare("ExchangeName", "direct", true, false, null); //声明交换器与备份交换器绑定
    2 Dictionary<string, object> arg = new Dictionary<string, object>();
    3 arg.Add("x-message-ttl", 5000);  //设置队列过期时间 5000ms
    4 channel.QueueDeclare("QueueName", true, false, false, arg);
    5 channel.QueueBind("QueueName", "ExchangeName", "RoutingKey", null);
    6 var basicProperties = channel.CreateBasicProperties();
    7 basicProperties.Expiration = "4000";  //设置消息过期时间 4000ms
    8 channel.BasicPublish("ExchangeName", "RoutingKey", basicProperties, Encoding.UTF8.GetBytes("helloword"));

      对于第一种设置队列 TTL 属性的方法,一旦消息过期,就会从队列中抹去,而在第二种方 法中,即使消息过期,也不会马上从队列中抹去,因为每条消息是否过期是在即将投递到消费者之前判定的。

    死信队列

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

      消息变成死信一般是由于以下几种情况:

    1. 消息被拒绝 (Basic.Reject/Basic .Nack),井且设置 requeue 参数为 false;
    2. 消息过期;
    3. 队列达到最大长度。

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

      

     1 channel.ExchangeDeclare("exchange.dlx", "direct", true);  //声明DLX
     2 channel.ExchangeDeclare("ExchangeName", "direct", true); //声明交换器与备份交换器绑定
     3 Dictionary<string, object> arg = new Dictionary<string, object>();
     4 arg.Add("x-dead-letter-exchange", "exchange.dlx");   //设置DLX
     5 arg.Add("x-dead-letter-routing-key", "routingkey"); //为私信消息重设路由键
     6 channel.QueueDeclare("QueueName", true, false, false, arg);
     7 channel.QueueDeclare("DlQueue",true,false,false);
     8 channel.QueueBind("QueueName", "ExchangeName", "RoutingKey", null);
     9 channel.QueueBind("DlQueue", "exchange.dlx", "routingkey");
    10 var basicProperties = channel.CreateBasicProperties();
    11 basicProperties.Expiration = "4000";  //设置消息过期时间 4000ms
    12 channel.BasicPublish("ExchangeName", "RoutingKey", basicProperties, Encoding.UTF8.GetBytes("helloword"));

       如果4s内消息没有被消费者消费,那么判定这条消息为过期,消息就会被丢给exchange.dlx,进而转发给DlQueue。

    死信队列 

      延迟队列存储的对象是对应的延迟消息,所谓"延迟消息"是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

      延迟队列可以通过设置消息的ttl和死信队列来实现,消费者订阅死信队列达到延迟效果。   

    过期时间(TTL)

  • 相关阅读:
    HDU3336 Count the string —— KMP next数组
    CodeForces
    51Nod 1627 瞬间移动 —— 组合数学
    51Nod 1158 全是1的最大子矩阵 —— 预处理 + 暴力枚举 or 单调栈
    51Nod 1225 余数之和 —— 分区枚举
    51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP
    51Nod 机器人走方格 V3 —— 卡特兰数、Lucas定理
    51Nod XOR key —— 区间最大异或值 可持久化字典树
    HDU4825 Xor Sum —— Trie树
    51Nod 1515 明辨是非 —— 并查集 + 启发式合并
  • 原文地址:https://www.cnblogs.com/jasonbourne3/p/11091390.html
Copyright © 2011-2022 走看看