EasyNetQ(RabbitMQ)在处理消息时,如果抛出异常,继续不断发送到订阅队列,不断处理(也就是不自动确认消息已到达)

默认情况下,EasyNetQ的消息处理过程中,如果throw exception,那么,依然是认为消息已经送达,不会再次推送,为了让RabbitMQ再次推送,可以这么实现:

复制代码
        public sealed class AlwaysRequeueErrorStrategy : IConsumerErrorStrategy
        {
            public void Dispose()
            {
            }

            public AckStrategy HandleConsumerError(ConsumerExecutionContext context, Exception exception)
            {
                return AckStrategies.NackWithRequeue;
            }

            public AckStrategy HandleConsumerCancelled(ConsumerExecutionContext context)
            {
                return AckStrategies.NackWithRequeue;
            }
        }

        [TestMethod]
        public void test()
        {
            var hostName = _configuration["RabbitMQ:HostName"];
            var mqport = _configuration["RabbitMQ:Port"];
            var userName = _configuration["RabbitMQ:UserName"];
            var password = _configuration["RabbitMQ:Password"];

            var connectionConfiguration = new ConnectionConfiguration
            {

                Hosts = new List<HostConfiguration>
                {
                    new HostConfiguration
                    {
                        Host = hostName,
                        Port = Convert.ToUInt16(mqport)
                    }
                },
                Port = Convert.ToUInt16(mqport),
                VirtualHost = "/",
                UserName = userName,
                Password = password
            };
            var _bus = RabbitHutch.CreateBus(connectionConfiguration , x=> {
                x.Register<IConsumerErrorStrategy, AlwaysRequeueErrorStrategy>();
            });

            var exchange = _bus.Advanced.ExchangeDeclare("ExchangeNAME_test", ExchangeType.Topic);
            
            var nickNameQu = _bus.Advanced.QueueDeclare("queuename2222");
            int count = 0;
            _bus.Advanced.Bind(exchange, nickNameQu, "RouterKey1");
            _bus.Advanced.Consume(nickNameQu, (data, properties, info) =>
            {
                count++;
                if (count < 2)
                    throw new Exception("my error");
                 var msg = Encoding.UTF8.GetString(data);
            });

            Task.Run(() => {
                _bus.PublishAsync(new UpdateAvaterMessage() {  Avater = "abcc22" }, "RouterKey1");
            });
           
            Thread.Sleep(100000);
        }
复制代码

原理是重写IConsumerErrorStrategy

(如果不是使用EasyNetQ,传统的RabbitMQ库是用手动ack实现)

另外,如果消息处理过程中,服务器死机,这种情况消息是会重发的,不需要担心

posted @   IWing  阅读(585)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示