Azure ServiceBusClient SendMessageAsync执行缓慢问题求助
排查Azure Service Bus SendMessageAsync性能问题
问题背景
当前调试的C#方法可正常将报告记录发布到Service Bus Topic,但单条SendMessageAsync调用耗时约1分45秒,报告总XML大小30k,单条记录约1k。对应代码如下:
public async Task PublishReport(string correlationId) { _methodName = nameof(GetReport); _correlationId = correlationId; LogInfo("Started"); DateTime now = DateTime.Now; DateTime lastPoll = await GetTimeOfLastPoll(_correlationId); List<AmxGetReportResponse> reportRecs = await GetReport(lastPoll, _correlationId); var credential = new ChainedTokenCredential( new ManagedIdentityCredential(), new VisualStudioCredential(), new AzureCliCredential() ); LogInfo($"Now logged into azure"); var serviceBusClient = new ServiceBusClient($"{_amxOptions.ServiceBusNamespace}.servicebus.windows.net", credential); LogInfo($"Have service bus client"); var topicSendClient = serviceBusClient.CreateSender(_amxOptions.ServiceBusTopicName); LogInfo($"Have topic sender"); foreach (var reportRec in reportRecs) { string msg = _amxReport2CatsUpdate.Execute(reportRec); LogInfo($"Mapped msg={msg}"); var serviceBusMsg = new ServiceBusMessage(msg); LogInfo($"Have service bus message"); await topicSendClient.SendMessageAsync(serviceBusMsg); LogInfo($"Sent msg to sb topic {_amxOptions.ServiceBusTopicName}: {msg}"); } await SetTimeOfLastPoll(now, _correlationId); LogInfo("Leaving"); }
排查优化步骤
1. 定位身份认证环节耗时
ChainedTokenCredential会按顺序尝试不同凭证类型,可能因无效凭证的重试等待拖慢速度。可以单独测试单种凭证的获取耗时,比如调试时仅使用AzureCliCredential,部署到Azure时仅使用ManagedIdentityCredential,排除认证环节的影响。
2. 调整Service Bus客户端配置
- 切换传输类型:默认使用
AmqpTcp,若网络存在防火墙或代理限制,尝试改为AmqpWebSockets:var clientOptions = new ServiceBusClientOptions { TransportType = ServiceBusTransportType.AmqpWebSockets }; var serviceBusClient = new ServiceBusClient($"{_amxOptions.ServiceBusNamespace}.servicebus.windows.net", credential, clientOptions); - 优化重试策略:默认重试策略可能在遇到临时问题时等待过久,可调整为更紧凑的重试规则:
var clientOptions = new ServiceBusClientOptions { RetryOptions = new ServiceBusRetryOptions { MaxRetries = 3, Delay = TimeSpan.FromSeconds(1), MaxDelay = TimeSpan.FromSeconds(5) } };
3. 改用批量发送减少网络往返
逐条发送会产生多次网络交互,累积延迟。改用批量发送可大幅减少请求次数:
var batchOptions = new CreateBatchOptions(); using var batch = await topicSendClient.CreateBatchAsync(batchOptions); foreach (var reportRec in reportRecs) { string msg = _amxReport2CatsUpdate.Execute(reportRec); var serviceBusMsg = new ServiceBusMessage(msg); if (!batch.TryAddMessage(serviceBusMsg)) { // 批量已满,发送当前批次 await topicSendClient.SendMessagesAsync(batch); // 创建新批次 batch.Dispose(); batch = await topicSendClient.CreateBatchAsync(batchOptions); batch.TryAddMessage(serviceBusMsg); } } // 发送剩余消息 if (batch.Count > 0) { await topicSendClient.SendMessagesAsync(batch); }
4. 排查网络环境问题
- 本地调试时,检查是否存在代理、防火墙限制AMQP端口(5671/5672),导致连接延迟过高。
- 若部署在Azure,确认应用所在区域与Service Bus命名空间区域是否一致,跨区域会增加网络传输延迟。
5. 细化日志与监控
- 在
SendMessageAsync前后添加精确计时日志,记录DateTime.UtcNow,确认耗时确实来自该方法,而非前后的序列化或日志操作。 - 查看Azure Portal中Service Bus命名空间的监控指标,重点关注入站消息延迟、服务器延迟,确认是否为服务端问题。
6. 升级SDK版本
检查当前使用的Azure.Messaging.ServiceBus SDK版本,旧版本可能存在性能缺陷,升级到最新稳定版后重新测试。
内容的提问来源于stack exchange,提问作者Rob Bowman
相关产品推荐
相关产品推荐

