【问题标题】:Azure Service Bus Send throughput .Net SDKAzure 服务总线发送吞吐量 .Net SDK
【发布时间】:2022-01-15 02:30:20
【问题描述】:

我目前正在实现一个库以更快地将消息发送到服务总线队列。观察到的是,如果我使用同一个ServiceBusClient,使用同一个sender并行发送消息的话,吞吐量并没有那么高,我的网络上传速度也没有得到充分利用。当我创建单个客户端并使用它们发送时,吞吐量会急剧增加,甚至可以很好地利用我的上传带宽。

我的理解是正确的还是必须由单个客户端发送者来做?另外,我不喜欢创建多个客户端,因为它会使用大量资源来建立客户端连接。有没有文章对此有所启发?

有一个吞吐量测试工具,它的代码也创建了多个客户端。

protected override Task OnStartAsync()
        {
            for (int i = 0; i < this.Settings.SenderCount; i++)
            {
                this.senders.Add(Task.Run(SendTask));
            }
            return Task.WhenAll(senders);
        }

        async Task SendTask()
        {
            var client = new ServiceBusClient(this.Settings.ConnectionString);
            ServiceBusSender sender = client.CreateSender(this.Settings.SendPath);
            var payload = new byte[this.Settings.MessageSizeInBytes];
            var semaphore = new DynamicSemaphoreSlim(this.Settings.MaxInflightSends.Value);
            var done = new SemaphoreSlim(1);
            done.Wait();
            long totalSends = 0;

https://github.com/Azure-Samples/service-bus-dotnet-messaging-performance

是否有一个库来管理池中的连接?

【问题讨论】:

    标签: azure azureservicebus azure-sdk-.net


    【解决方案1】:

    根据您代码中的模式,我假设您使用的是Azure.Messaging.ServiceBus 包。如果不是这种情况,请忽略本文的其余部分。

    ServiceBusClient 表示到服务的单个 AMQP 连接。从此客户端产生的任何发送者、接收者和处理器都将共享该连接。这使您的应用程序能够控制使用的连接数,并以最适合您的上下文的方式将它们汇集起来。

    建议在应用程序的整个生命周期内重用客户端、发送方、接收方和处理器;尽管连接是共享的,但每次产生新的子类型时,它都必须建立新的 AMQP 链接并执行授权握手 - 这是不小的开销。

    这些类型在资源方面是自我管理的。在空闲期间,连接和链接将被关闭以避免浪费,并且它们将自动为第一个需要它们的操作重新创建。

    关于使用多个客户端、发送器、接收器和处理器 - 这是一种有效的方法,并且在某些情况下可以产生更好的性能。我要提到的一个警告是,在主机环境中使用比 CPU 内核数量更多的客户端会增加导致线程池争用的风险。 Service Bus 库是高度异步的,其性能依赖于及时安排异步调用的延续。

    不幸的是,性能调整很难一概而论,因为它对于不同的应用程序和托管环境有很大的不同。要找到正确数量的发送方以最大限度地提高应用程序的吞吐量,我们建议您花时间测试不同的值并观察特定系统中的性能特征。

    【讨论】:

      【解决方案2】:
      • 对于新的 SDK,应用了相同的连接管理原则,即重新创建连接的成本很高。
      • 您可以将客户端对象直接连接到总线或通过创建 ServiceBusConnection,可以在客户端之间共享单个连接

      这是为了让场景尽可能多地向单个队列发送消息,然后您可以通过在不同线程上启动多个 ServiceBusConnection 和客户端对象来增加吞吐量。

      是否有一个库来管理池中的连接?

      在底层没有连接池,创建新连接的成本相对较高。对于以前的 SDK,建议是尽可能re-use factories and clients

      请参阅此article 了解更多信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-10
        • 2014-12-21
        • 2021-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-07
        • 2020-09-02
        • 1970-01-01
        相关资源
        最近更新 更多