Azure Service Bus连接异常时MassTransit重试策略未按配置生效求助
问题描述
创建了一个使用MassTransit对接Azure Service Bus的控制台应用,配置代码如下:
using System; using System.Threading.Tasks; using GreenPipes; using MassTransit; using Microsoft.Extensions.Azure; namespace MassTransitRetryExample { class Program { static async Task Main(string[] args) { var busControl = Bus.Factory.CreateUsingAzureServiceBus(cfg => { cfg.Host("My Service Bus Connection string"); cfg.UseRetry(retryConfig => { retryConfig.Exponential(6, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5)); }); cfg.ReceiveEndpoint("testqueue", ep => { ep.Consumer<YourMessageConsumer>(); }); }); await busControl.StartAsync(); Console.WriteLine("Sending a message..."); await busControl.Publish(new YourMessage { Text = "Hello, World!" }); Console.WriteLine("Press any key to stop receiving messages."); Console.ReadKey(); await busControl.StopAsync(); } }
当使用错误的Service Bus连接字符串导致连接失败时,系统抛出异常且仅重试4次,而非配置的6次,异常信息如下:
System.AggregateException: Retry failed after 4 tries. Retry settings can be adjusted in ClientOptions.Retry. (No such host is known. (my-bus.servicebus.windows.net:443)) (No such host is known. (my-bus.servicebus.windows.net:443)) (No such host is known. (my-bus.servicebus.windows.net:443)) (No such host is known. (my-bus.servicebus.windows.net:443))
Azure.RequestFailedException: No such host is known. (my-bus.servicebus.windows.net:443)
System.Net.Http.HttpRequestException: No such host is known. (my-bus.servicebus.windows.net:443)
System.Net.Sockets.SocketException (11001): No such host is known.
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at System.Net.Sockets.Socket.g__WaitForConnectWithCancellation|277_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
使用版本:MassTransit 7.3.0、MassTransit.Azure.ServiceBus.Core 7.3.0。
原因分析
cfg.UseRetry的作用范围不覆盖连接阶段:你配置的cfg.UseRetry是针对消息消费阶段的异常重试,仅在消费者处理消息抛出异常时生效,完全不涉及总线与Azure Service Bus建立连接阶段的错误。- 4次重试来自Azure Service Bus客户端SDK默认策略:连接失败属于Azure Service Bus客户端SDK层面的错误,这部分的重试由SDK自带的默认策略控制,默认重试次数为4次,因此会看到4次重试后抛出异常。
解决方法
要调整连接阶段的重试策略,需要在cfg.Host的配置中单独设置Azure Service Bus客户端的重试规则,而非使用全局的UseRetry。修改后的代码如下:
var busControl = Bus.Factory.CreateUsingAzureServiceBus(cfg => { cfg.Host("My Service Bus Connection string", h => { // 配置连接阶段的重试策略 h.Retry(r => { r.Exponential(6, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5)); }); }); // 此配置仅针对消息消费阶段的异常重试,与连接错误无关 cfg.UseRetry(retryConfig => { retryConfig.Exponential(6, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5)); }); cfg.ReceiveEndpoint("testqueue", ep => { ep.Consumer<YourMessageConsumer>(); }); });
配置后,连接阶段的重试次数会按照设置的6次执行,消费阶段的重试依然由cfg.UseRetry控制。
内容的提问来源于stack exchange,提问作者Manoj Bang

