MassTransit多UseMessageRetry策略下重试计数器异常重置问题咨询
问题:MassTransit多独立重试策略的计数器重置异常
环境与配置
使用MassTransit 8 + Amazon SQS/SNS,应用部署在Windows Docker容器中。单个消费者MySingleConsumer会抛出三种异常:EndpointNotFoundException、TimeoutException、SocketException。为分别处理这三种异常,配置了3个独立的重试策略,代码如下:
builder.Services .Configure<AmazonSqsTransportOptions>(configuration.GetSection("MassTransit:Transports:AmazonSqs")) .AddMassTransit(bus => { bus.AddDelayedMessageScheduler(); bus.AddConsumer<MySingleConsumer>(); bus.UsingAmazonSqs((context, sqs) => { var entityNameFormatter = new MessageNameFormatterEntityNameFormatter(new AmazonSqsMessageNameFormatter()); var options = context.GetRequiredService<IOptions<AmazonSqsTransportOptions>>().Value; sqs.MessageTopology.SetEntityNameFormatter(new PrefixEntityNameFormatter(entityNameFormatter, options.Scope)); sqs.ConfigureEndpoints(context, new KebabCaseEndpointNameFormatter(options.Scope)); sqs.UseDelayedMessageScheduler(); sqs.UseMessageRetry(r => { r.Handle(typeof(EndpointNotFoundException)); r.Interval(3, TimeSpan.FromSeconds(10)); }); sqs.UseMessageRetry(r => { r.Handle(typeof(TimeoutException)); r.Interval(3, TimeSpan.FromSeconds(20)); }); sqs.UseMessageRetry(r => { r.Handle(typeof(SocketException)); r.Interval(3, TimeSpan.FromSeconds(30)); }); }); });
问题现象
当同一类型异常连续出现3次时,重试策略可正常工作(3次重试后抛出异常);但当异常类型随机切换时,之前的异常重试计数器会被重置,导致需要重新累计3次才会触发抛出:
EndpointNotFoundException连续出现3次→下次该异常会被抛出(符合预期)EndpointNotFoundException连续出现3次后,出现1次TimeoutException→前者计数器重置为0,需再次连续出现3次才会抛出(不符合预期)SocketException出现3次、TimeoutException出现3次、SocketException再出现3次→此时才会抛出SocketException(不符合预期)SocketException出现1次、TimeoutException出现2次、EndpointNotFoundException出现2次→需SocketException再连续出现3次才会抛出(不符合预期)
简言之,重试计数器仅跟踪最后一次出现的异常类型的重试次数,异常类型切换时计数器重置,可能导致无限重试循环。
排查发现
将所有异常声明在同一个UseMessageRetry()策略中时,计数器可正常工作;使用多个独立的sqs.UseMessageRetry()方法分别处理不同异常时,出现上述问题。
疑问
是否是对MassTransit重试策略工作原理存在误解?还是该情况属于bug,需要在GitHub提交issue?
内容的提问来源于stack exchange,提问作者JohnyMotorhead
相关产品推荐
相关产品推荐

