ServiceBusClient SendMessageAsync 非常慢

huangapple go评论49阅读模式
英文:

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(&quot;Started&quot;);

        DateTime now = DateTime.Now;
        DateTime lastPoll = await GetTimeOfLastPoll(_correlationId);

        List&lt;AmxGetReportResponse&gt; reportRecs = await GetReport(lastPoll, _correlationId);
        var credential = new ChainedTokenCredential(
                                new ManagedIdentityCredential(),
                                new VisualStudioCredential(),
                                new AzureCliCredential()
                                );
        LogInfo($&quot;Now logged into azure&quot;);
        var serviceBusClient = new ServiceBusClient($&quot;{_amxOptions.ServiceBusNamespace}.servicebus.windows.net&quot;, credential);
        LogInfo($&quot;Have service bus client&quot;);
        var topicSendClient = serviceBusClient.CreateSender(_amxOptions.ServiceBusTopicName);
        LogInfo($&quot;Have topic sender&quot;);

        foreach (var reportRec in reportRecs)
        {
            string msg = _amxReport2CatsUpdate.Execute(reportRec);
            LogInfo($&quot;Mapped msg={msg}&quot;);
            var serviceBusMsg = new ServiceBusMessage(msg);
            LogInfo($&quot;Have service bus message&quot;);
            await topicSendClient.SendMessageAsync(serviceBusMsg);
            LogInfo($&quot;Sent msg to sb topic {_amxOptions.ServiceBusTopicName}: {msg}&quot;);
        }

        await SetTimeOfLastPoll(now, _correlationId);
        LogInfo(&quot;Leaving&quot;);
    }

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.

huangapple
  • 本文由 发表于 2023年5月25日 18:59:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76331555.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定