Azure 服务总线的 ServiceBusClient - 重用 tcp 连接,就像 HttpClientFactory 一样

Dav*_*son 1 c# azureservicebus httpclientfactory .net-5

我有许多 CRUD API,它们通过 HTTP 调用 (.NET 5) 相互通信。
为了避免打开太多的 tcp 连接,我在所有这些服务中通过 DI使用HttpClientFactory 。这效果很好,我没有遇到太多通过 HTTP 打开的连接。

但我的 Azure 应用服务仍然抱怨 SNAT 连接过多:

在此输入图像描述

我猜原因是Azure服务总线。我的 API 的每次调用都会将事件写入总线。
为此,我在每次调用时创建一个新实例:

            await using (ServiceBusClient client = new ServiceBusClient(_serviceBusConnectionString))
                {
                    var messageObject = new { message.Name, message.Body };
                    var messageJson = JsonConvert.SerializeObject(messageObject);
                    ServiceBusSender sender = client.CreateSender(_topicName);
                    await sender.SendMessageAsync(new ServiceBusMessage(messageJson));
                }
Run Code Online (Sandbox Code Playgroud)

许多开发人员都像这样使用 HttpClient(这是一个坏主意,请阅读上面的文章中的原因)。HttpClient 的解决方案是 .NET 为此目的提供的 AddHttpClient 方法。

但是 Azure 服务总线呢?没有什么像 AzureServiceBusFactory 之类的东西,将 AzureServiceBus 添加为单例并不是一个好主意,因为每次调用的配置都应该不同。

如何确保连接池也重新用于 Azure 服务总线连接?我错过了什么最佳实践吗?或者您认为连接问题还有其他原因吗?

编辑:

接受的答案是正确的。这工作正常,我的错误消失了。只需使用以下命令添加服务总线客户端:

            services.AddAzureClients(cfg =>
            {
                cfg.AddServiceBusClient("your-connection-string");
            });
Run Code Online (Sandbox Code Playgroud)

之后,您就可以在您的所有服务中轻松通过 DI 获得客户。

Gau*_*tri 6

但是 Azure 服务总线呢?没有什么像 AzureServiceBusFactory 之类的东西,将 AzureServiceBus 添加为单例并不是一个好主意,因为每次调用的配置都应该不同。

事实上恰恰相反。服务总线团队建议,与服务总线的连接应注册为仅使用的单例ServiceBusClientBuilderExtensions,不应在每次操作后关闭或处置。

由此link

与服务交互的服务总线对象(例如 ServiceBusClient、ServiceBusSender、ServiceBusReceiver 和 ServiceBusProcessor)应注册为单例(或实例化一次并共享)以进行依赖项注入。可以使用 ServiceBusClientBuilderExtensions 注册 ServiceBusClient 以进行依赖项注入。

我们建议您在发送或接收每条消息后不要关闭或处置这些对象。关闭或处置特定于实体的对象(ServiceBusSender/Receiver/Processor)会导致断开与服务总线服务的链接。处置 ServiceBusClient 会导致断开与服务总线服务的连接。

请参阅此链接以获取服务总线团队的完整建议:https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-performance-improvements ?tabs=net-standard-sdk- 2 .

  • 虽然服务总线客户端成为单例,但服务总线发送者和接收者却不是,通过“ServiceBusClientBuilderExtensions”。有没有办法将“ServiceBusSender”作为依赖项注入?我找不到像您在答案中提到的那样的任何文章。 (4认同)