如何提升向Azure Service Bus发送消息的速度?
问题
将以下Azure Function部署在Azure英国南部区域,向同区域的Service Bus发送消息。当前发送1000条消息耗时25秒,约40条/秒,远达不到性能需求。注意:实际场景中需要严格按照数据库中消息的顺序,依次发送至不同的队列/主题,因此无法使用批量发送方式。请问有哪些方法可以提升发送速度?
using System.Diagnostics; using System.Net; using Azure.Messaging.ServiceBus; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Extensions.Logging; namespace Speedtest { public class Function1 { private readonly ILogger _logger; public Function1(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger<Function1>(); } [Function("Function1")] public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req) { var client = new ServiceBusClient("...omitted..."); var sender = client.CreateSender("customercreated"); var sw = Stopwatch.StartNew(); for (int i = 0; i < 1000; i++) { var message = new ServiceBusMessage($"Hahaahahaha{i}"); await sender.SendMessageAsync(message); } sw.Stop(); var response = req.CreateResponse(HttpStatusCode.OK); response.Headers.Add("Content-Type", "text/plain; charset=utf-8"); response.WriteString($"Time taken was {sw.ElapsedMilliseconds}"); return response; } } }
优化方案
复用ServiceBusClient和Sender实例
当前代码每次函数调用都创建新的ServiceBusClient和ServiceBusSender,会产生额外的连接建立开销。ServiceBusClient设计为单例使用,应在函数启动时初始化并全局复用;ServiceBusSender也可针对目标队列/主题复用,避免重复创建带来的资源消耗。可控异步并行发送(维持顺序)
虽然不能批量发送,但可以在保证顺序的前提下做并行处理:- 若发送到同一队列/主题,可将消息分成小批次,批次内并行发送,批次间按顺序执行,既提升吞吐量又保证整体顺序。
- 若发送到不同队列/主题,可直接并行发送不同目标的消息,只要同一目标的消息顺序维持即可。可使用
Task.WhenAll处理异步任务组,但需控制并发数量,避免触发Service Bus限流。
调整Service Bus客户端配置
通过ServiceBusClientOptions优化连接参数:- 切换
TransportType为AmqpWebSockets(若默认用AmqpTcp),提升网络适配性; - 调整
RetryOptions减少不必要的重试等待时间; - 设置合理的
ConnectionIdleTimeout避免连接过早关闭; - 增大客户端并发连接数配置,提升发送并行能力。
- 切换
升级Azure Function运行资源
当前函数的运行环境可能成为瓶颈:- 将函数从消费计划改为高级计划或专用计划,提升CPU、内存资源;
- 调整函数实例数和并发度设置,让函数有更多资源处理发送任务。
启用Service Bus分区队列/主题
若目标队列/主题支持,启用分区功能。分区会将消息分散到多个容器中,提升整体吞吐量,且单分区内的消息顺序不受影响,完全符合按序发送的需求。预创建ServiceBusMessage实例
提前批量创建ServiceBusMessage对象,避免循环内重复创建的累积开销,虽单个影响微小,但1000条消息的累积效应可节省一定时间。
内容的提问来源于stack exchange,提问作者Peter Morris
相关产品推荐
相关产品推荐

