zoukankan      html  css  js  c++  java
  • RabbitMQ Dead Lettering(死信)

    死信,顾名思义,就是死掉的消息,死掉的消息是会被一般的队列丢弃的。如果这些消息很重要,而我们又需要,怎么办?凡事都有一个退路,现在就有一种方法可将这些死信消息存下来,那就是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="123456",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",10000} //设置消息的存活时间,即过期时间
                                             });
                                             
                        //将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

  • 相关阅读:
    Android Zygote介绍
    Android binder介绍(下)
    Android binder介绍(上)
    Android init介绍(下)
    Android init介绍(上)
    Android 网络服务介绍
    Linux代理服务器使用
    Linux ALSA介绍
    ZigBee MAC层(下)
    ZigBee MAC层(上)
  • 原文地址:https://www.cnblogs.com/williamwsj/p/8108970.html
Copyright © 2011-2022 走看看