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 获得客户。
但是 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 .