• 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)

  • 相关阅读:
    android 学习
    android 学习
    android 学习
    android 学习
    android 学习
    android 学习
    android 学习
    android 学习
    android 学习
    每日日报
  • 原文地址:https://www.cnblogs.com/jasonbourne3/p/11091390.html
Copyright © 2020-2023  润新知