.net core 下使用 RabbitMQ 死信队列 (二)

   消息到死信队列的三种情况  
  1. 消息被拒(basic.reject or basic.nack)并且没有重新入队(requeue=false);
  2. 当前队列中的消息数量已经超过最大长度。
  3. 消息在队列中过期,即当前消息在队列中的存活时间已经超过了预先设置的TTL(Time To Live)时间;

     

     

 

 以下是代码实现

发送到消息  其实就是 正常队列 挂 死信队列

 1  /// <summary>
 2         ///发送消息(死信队列)
 3         /// </summary>
 4         /// <param name="msg"></param>
 5         public void DLXSend(string msg)
 6         {
 7             //正常队列
 8             var exchangeNormal = "normal.exchange";
 9             var routeNormal = "normal.routekey";
10             var queueNormal = "normal.queue";
11             //死信队列
12             var exchangeDLX = "dlx.exchange";
13             var routeDLX = "dlx.route";
14             var queueDLX = "dlx.queue";
15 
16             this.Connection();
17             IModel channel = this._connection.CreateModel();
18             //死信队列交换机
19             channel.ExchangeDeclare(exchangeDLX, ExchangeType.Fanout, true, false, null);
20             //死信队列
21             channel.QueueDeclare(queueDLX, true, false, false);
22 
23             channel.QueueBind(queueDLX, exchangeDLX, routeDLX);
24 
25             //正常队列交换机
26             channel.ExchangeDeclare(exchangeNormal, ExchangeType.Fanout, true, false);
27             //正常队列
28             channel.QueueDeclare(queueNormal, true, false, false, new Dictionary<string, object> {
29                                              { "x-dead-letter-exchange",exchangeDLX}, //设置当前队列交换机的DLX
30                                              { "x-dead-letter-routing-key",routeDLX}, //设置DLX的路由key,DLX会根据该值去找到死信消息存放的队列
31                                              { "x-message-ttl",30000} //设置消息的存活时间,即过期时间 30秒
32                                          });
33             //绑定正常交换机
34             channel.QueueBind(queueNormal, exchangeNormal, routeNormal);
35 
36             var properties = channel.CreateBasicProperties();
37             properties.Persistent = true;
38             //发布消息
39             channel.BasicPublish(exchange: exchangeNormal,
40                                  routingKey: routeNormal,
41                                  basicProperties: properties,
42                                  body: Encoding.UTF8.GetBytes("hello rabbitmq message"));
43 
44         }

消费死信队列的消息

 1 /// <summary>
 2         /// 接收死信队列
 3         /// </summary>
 4         public void ReceiveDLX(Func<string,bool>func)
 5         {
 6             //建立连接
 7             Connection();
 8             //建立信道
 9             IModel channel = this._connection.CreateModel();
10             //死信队列交换机
11             channel.ExchangeDeclare("dlx.exchange", ExchangeType.Fanout, true, false, null);
12             //死信队列
13             channel.QueueDeclare("dlx.queue", true, false, false);
14 
15             channel.QueueBind("dlx.queue", "dlx.exchange", "dlx.route", null);
16 
17             var consumer = new EventingBasicConsumer(channel);
18             consumer.Received += (object? sender, BasicDeliverEventArgs e) =>
19             {
20                 byte[] bytes = e.Body.ToArray();
21                 string recevieMessage = Encoding.UTF8.GetString(bytes);
22                 if (func(recevieMessage))
23                 {
24                     //这里是收到消息后 手动确认接收到消息也就是手动ACK
25                     channel.BasicAck(e.DeliveryTag, false);
26                 }
27                 else
28                 {
29                     //拒收,是接收端在收到消息的时候响应给RabbitMQ服务的一种命令,
30                     //告诉服务器不应该由我处理,或者拒绝处理,扔掉。接收端在发送reject命令的时候可以选择是
31                     //否要重新放回queue中。
32                     //如果没有其他接收者监控这个queue的话,要注意一直无限循环发送的危险。
33                     channel.BasicReject(deliveryTag: e.DeliveryTag, requeue: true);//放回队列--重新包装信息,放入其他队列
34                 }
35             };
36             // 3、消费消息
37             channel.BasicQos(0, 1, false); // Qos(防止多个消费者,能力不一致,导致的系统质量问题。 每一次一个消费者只成功消费一个)
38             channel.BasicConsume("dlx.queue", false, consumer);
39         }

 

 

 

测试结果 正常队列 1条信息 30秒后 进入到死信队列中

 

 消息已经进入到死信队列中了

 

 

 

 死信队列消息被消费了

 

posted on 2023-01-31 21:18  是水饺不是水饺  阅读(60)  评论(0编辑  收藏  举报

导航