以下 Azure 函数在 Azure(英国南部)上运行,并将消息发布到同样位于英国南部的服务总线。
这需要 25 秒,这意味着我每秒收到大约 40 条消息,这还远远不够。
请注意,我的实际要求是按顺序将消息发送到各个队列/主题,以便在数据库中找到它们,因此我无法使用批量发送。
有没有办法加快速度,因为每秒 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
和 ServiceBusSender
,因此每次发送一条消息时,您都需要支付建立连接、建立链接和授权的费用。
我们建议将 Azure SDK 客户端视为单例,最好利用函数主机的依赖项注入。这可确保正确管理客户端生命周期并进行处置。使用 DI 注册服务总线类型的示例可以在概述的本节中找到,更多讨论和示例可以在文章使用 Azure SDK for .NET 进行依赖注入中找到。
需要注意的一件事是,存在与客户端(默认为 60 秒)和服务(在撰写本文时为 30 分钟)相关的空闲超时。如果您的函数不经常被调用,您可能需要调整创建 ServiceBusClient
时传递的选项的
ConnectionIdleTimeout属性。服务空闲超时时间不可调整;如果您发送的频率低于服务间隔,您别无选择,只能支付连接费用。
代码中最慢的部分是循环,而不是创建。循环本身大约需要 25 秒来执行。
这是预期的,因为代码正在发送每条消息并等待操作完成。为了加快速度,请发送每条消息并将拍摄的参考保存在集合中,等待完成所有任务,
Task.WhenAll
。