英文:
ServiceBusClient SendMessageAsync very slow
问题
以下是您要翻译的内容:
我有以下在 vscode 中调试的方法:
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");
}
它确实可以工作,并且会为报告的每个记录发布一条消息。报告 XML 的总大小为 30KB,每个记录约为 1KB。
我的问题是,运行 SendMessageAsync 方法大约需要 1 分钟 45 秒?
英文:
I have the following method that I'm debugging in vscode:
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");
}
It does work and will publish a message for each record of the report. The total size of the report xml is 30k and each record is approx 1k.
My problem is, it takes roughly 1 min 45 seconds for the SendMessageAsync method to run?
答案1
得分: 0
Service Bus客户端应被视为长期存在的对象,理想情况下应被视为单例。(文档)
你在这里使用的模式要求每次调用 PublishReport
都会创建一个新连接,执行身份验证,打开一个连接,以及执行授权操作。因为所有这些操作都是在第一次服务操作被请求时才会延迟执行,所以你的第一次调用 SendMessagesAsync
就会付出这些成本。
我怀疑大部分时间都花在尝试获取凭据上。我建议收集 Azure.Identity 日志来帮助理解选择了哪个凭据以及是否发生了失败/重试。那份指南中描述的方法还会捕获 Service Bus 日志,当发送开始和完成时会生成一个条目,这将允许你计算实际服务操作花费了多长时间。具体来说,你需要查找来自“Azure-Messaging-ServiceBus” 事件源 的事件1、2和3。
值得注意的是,Service Bus客户端不会被 PublishReport
销毁,这将使连接被遗弃直到超时,可能会因网络堆栈中的争用而导致延迟。
英文:
Service Bus clients are intended to be long-lived and, ideally, treated as singletons. (docs)
The pattern that you're using here requires that a new connection be created, authentication be performed, a link opened, and authorization to be performed for each call to PublishReport
. Because all of that happens lazily when the first service operation is requested, your first call to SendMessagesAsync
is paying the cost.
I suspect that the majority of the time is being spent attempting to acquire a credential. I'd suggest collecting Azure.Identity logs to help understand what credential is being selected and whether failures/retries are taking place. The approach described in that guide will also capture Service Bus logs, which emit an entry when sending starts and completes which would allow you to calculate how long the actual service operation took. Specifically, you'll be looking for events 1, 2, and 3, from the "Azure-Messaging-ServiceBus" event source.
It is also worth noting that the Service Bus clients are not disposed by PublishReport
, which will orphan connections until they timeout, potentially causing delays due to contention in the network stack.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论