为何MassTransit+Azure Service Bus使用HTTP长轮询而非AMQP?
我们的应用使用MassTransit对接Azure Service Bus,配置代码如下:
x.UsingAzureServiceBus((context, cfg) => { var connectionString = builder.Configuration.GetConnectionString("AzureServiceBusEndpoint") ?? throw new Bug("Service bus configuration is missing"); cfg.Host( new UriBuilder("sb", new Uri(connectionString).Host).Uri, configurator => configurator.TokenCredential = credential); cfg.ConfigureEndpoints(context); });
功能运行正常,但在依赖追踪中发现,每个已配置的主题都会定期向ASB主机发起请求,每次持续60秒后重复。原本期望应用通过AMQP协议保持TCP长连接,现在有两个疑问:
- 是不是哪里配置遗漏了?
- 是否需要额外启用AMQP相关选项?
在Application Insights中看到的依赖追踪记录(数量多达数千条)示例如下:
timestamp: 2024-07-26T10:00:59.3023196Z id: b27b6a75a8991bee target: ourservername-asb-dev.servicebus.windows.net/WorkItemStageChangedNotification type: Azure Service Bus name: ServiceBusReceiver.Receive success: True duration: 59997.8184 performanceBucket: 30sec-1min itemType: dependency customDimensions: {"AspNetCoreEnvironment":"Staging","_MS.ProcessedByMetricExtractors":"(Name:'Dependencies', Ver:'1.1')"} operation_Id: c87b305ea70a107ddb66407c4242e3e1 operation_ParentId: c87b305ea70a107ddb66407c4242e3e1 application_Version: 8.0 client_Type: PC client_IP: 0.0.0.0 client_City: Boydton client_StateOrProvince: Virginia client_CountryOrRegion: United States cloud_RoleName: notifications-dev cloud_RoleInstance: noti_951344198b sdkVersion: dotnetc:2.21.0-429 itemId: 2e6eebf2-4b36-11ef-94c2-000d3a04ebf3 itemCount: 1
1. 澄清:60秒请求是AMQP长轮询的正常表现
你在Application Insights里看到的ServiceBusReceiver.Receive记录,是Azure Service Bus SDK的长轮询机制:当消费者没有消息可接收时,会保持一个60秒的等待请求(SDK默认接收超时时间),超时后自动重试,这是AMQP协议下的正常行为,目的是减少空轮询频率、提升效率。
但如果实际走了HTTPS(AMQP over WebSocket)而非AMQP TCP长连接,大概率是网络环境限制导致SDK自动降级。
2. 配置修正:强制指定AMQP TCP传输
当前配置未显式指定传输类型,虽然SDK默认用AMQP TCP,但如果网络中5671端口(AMQP TCP默认端口)被防火墙/代理拦截,SDK会自动 fallback到AMQP over WebSocket(走443端口)。
可以在Host配置中显式指定传输类型,强制使用AMQP TCP:
x.UsingAzureServiceBus((context, cfg) => { var connectionString = builder.Configuration.GetConnectionString("AzureServiceBusEndpoint") ?? throw new Bug("Service bus configuration is missing"); cfg.Host( new UriBuilder("sb", new Uri(connectionString).Host).Uri, configurator => { configurator.TokenCredential = credential; // 强制使用AMQP TCP传输 configurator.TransportType = Azure.Messaging.ServiceBus.ServiceBusTransportType.AmqpTcp; }); cfg.ConfigureEndpoints(context); });
3. 验证传输协议是否生效
可以通过两种方式确认:
- 查看应用的网络连接,确认是否有持续的TCP连接到ASB的5671端口
- 在Azure Portal的Service Bus命名空间「指标」中,查看
AMQP Connections指标,确认连接数稳定(而非频繁创建销毁)
4. 大量依赖追踪记录的优化
如果数千条记录造成困扰,可以调整Application Insights的采样规则,或者针对ServiceBusReceiver的操作设置过滤规则,减少不必要的追踪条目。另外,确保MassTransit消费者配置合理,避免创建过多不必要的独立消费者实例。
内容的提问来源于stack exchange,提问作者Michael Korbakov

