EasyNetQ异常处理

代码下载

https://download.csdn.net/download/u010312811/11252093

官方Demo

https://github.com/EasyNetQ/EasyNetQ/issues/793

 

1.新建项目

创建一个控制台程序,并添加对 EasyNetQ的引用

 

2.创建消息模型

2.1创建Answer

创建Answer数据模型

1     public class Answer
2     {
3         public string Text { get; }
4 
5         public Answer(string text)
6         {
7             Text = text;
8         }
9     }

2.2创建Question

1     public class Question
2     {
3         public string Text { get; }
4 
5         public Question(string text)
6         {
7             Text = text;
8         }
9     }

 

3.测试程序

3.1初始化代码

 1    private static IBus bus;
 2    private const string ErrorQueue = "EasyNetQ_Default_Error_Queue";
 3 
 4    static void Main(string[] args)
 5    {
 6         bus = RabbitHutch.CreateBus("host=localhost");
 7         /*订阅消息*/
 8         Subscribe();
 9 
10         /*处理错误队列中的错误数据*/
11         HandleErrors();
12 
13         /*发布消息*/
14         Console.WriteLine("输入文字,按回车发送消息!");
15         while (true)
16         {
17             var msg = Console.ReadLine();
18             bus.Publish(new Question(msg));
19         }
20     }

创建一个总线,用于消息的收发;

依次注册消息的订阅方法,错误处理方法,消息发布方法。

 

3.2消息订阅

 1     private static void Subscribe()
 2     {
 3         /*声明两个消费者*/
 4         bus.SubscribeAsync<Question>("subscriptionId", x => HandleMessageAsync(x).Invoke(1));
 5         bus.SubscribeAsync<Question>("subscriptionId", x => HandleMessageAsync(x).Invoke(2));
 6     }
 7 
 8     private static Func<int,Task> HandleMessageAsync(Question question)
 9     {
10         return async (id) =>
11         {
12             if (new Random().Next(0, 2) == 0)
13             {
14                 Console.WriteLine("Exception Happened!!!!");
15                 throw new Exception("Error Hanppened!");
16             }
17             else
18             {
19                 Console.WriteLine(string.Format("worker:{0},content:{1}", id, question.Text));
20             }
21         };
22     }

订阅方法中声明了两个消息的订阅者(因为 subscriptionId相同,所以消息会采取轮询的方法,依次发送到每个消息的消费者)。

消息处理中产生随机数,进而有33%的机会产生异常

3.3消息发布

1     var msg = Console.ReadLine();
2     bus.Publish(new Question(msg));

发布程序很简单,读取输入的内容,直接使用EasyNetQ提供的发布方法即可。

3.4异常处理

 

 1     private static void HandleErrors()
 2     {
 3         Action<IMessage<Error>, MessageReceivedInfo> handleErrorMessage = HandleErrorMessage;
 4 
 5         IQueue queue = new Queue(ErrorQueue, false);
 6         bus.Advanced.Consume(queue, handleErrorMessage);
 7     }
 8 
 9     private static void HandleErrorMessage(IMessage<Error> msg, MessageReceivedInfo info)
10     {
11         Console.WriteLine("catch: " + msg.Body.Message);
12     }

 

异常处理程序订阅了队列“EasyNetQ_Default_Error_Queue”,当异常发生时,EasyNetQ默认的处理是将队列数据写入当前的错误队列中。

 

 

4.功能测试

 当程序异常时,打印异常

 

5.异常重试

实际项目中,当程序发生异常后,我们期望的处理可能是将消息返回到原有队列,进行再次的数据处理。

修改bus创建的声明:

bus = RabbitHutch.CreateBus("host=localhost", x => x.Register<IConsumerErrorStrategy>(_ => new AlwaysRequeueErrorStrategy()));
AlwaysRequeueErrorStrategy是我们默认的错误处理方法
 1     public sealed class AlwaysRequeueErrorStrategy : IConsumerErrorStrategy
 2     {
 3         public void Dispose()
 4         {
 5         }
 6 
 7         public AckStrategy HandleConsumerError(ConsumerExecutionContext context, Exception exception)
 8         {
 9             return AckStrategies.NackWithRequeue;
10         }
11 
12         public AckStrategy HandleConsumerCancelled(ConsumerExecutionContext context)
13         {
14             return AckStrategies.NackWithRequeue;
15         }
16     }

 

 

posted @ 2019-06-21 11:50  imstrive  阅读(1487)  评论(0编辑  收藏  举报