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)

猜你喜欢

转载自www.cnblogs.com/jasonbourne3/p/11091390.html