通过 DI 注入到 ServiceBusTrigger Azure 函数中的 IHttpClientFactory 是不是为每个触发器重用或重新创建?
Posted
技术标签:
【中文标题】通过 DI 注入到 ServiceBusTrigger Azure 函数中的 IHttpClientFactory 是不是为每个触发器重用或重新创建?【英文标题】:Is an IHttpClientFactory that is injected via DI into a ServiceBusTrigger Azure function reused or recreated for each trigger?通过 DI 注入到 ServiceBusTrigger Azure 函数中的 IHttpClientFactory 是否为每个触发器重用或重新创建? 【发布时间】:2021-05-31 12:28:51 【问题描述】:我有一个带有一个 ServiceBusTrigger 的 Azure Function 项目。随着消息被添加到服务总线队列中,这可能会在短时间内迅速触发。据我了解,在将 IHttpClientFactory 注入 Azure Functions 项目时,工厂将暂时添加,据我了解,每个函数执行一次。
据我从文档中可以看出,这里并不理想——对于这样一个函数,我当然希望每次触发函数方法时都可以重用一个 HttpClientFactory,然后通过 httpClientFactory.CreateClient() 创建 HttpClients,正确的?恐怕通过 DI 暂时添加 IHttpClientFactories,它们将各自使用自己的连接池,进而可能会淹没连接限制。
谁能告诉我我是否理解正确,如果理解正确,我能做些什么来解决这个问题?
提前致谢。
【问题讨论】:
【参考方案1】:IHttpClientFactory
在被services.AddHttpClient()
添加时注册为单例,因此它是共享的,而不是每次都重新创建。检查代码here
关于 HttpClient
对象创建 - 查看 Microsoft 的文档 - here
问题不在于 HttpClient 本身,而在于 HttpClient 的默认构造函数,因为它创建了一个新的 HttpMessageHandler
的具体实例,该实例存在套接字耗尽和 DNS 更改问题。
为了解决上述问题并使HttpClient
实例易于管理,.NET Core 2.1 引入了IHttpClientFactory
接口,该接口可用于通过依赖注入 (DI) 在应用程序中配置和创建HttpClient
实例。管理HttpMessageHandler
的生命周期以避免在管理HttpClient
生命周期时可能出现的上述问题/问题。
在内部,每次要求从 IHttpClientFactory 创建 HttpClient
对象时,都会返回一个新实例。但是每个HttpClient
使用一个HttpMessageHandler
,它被IHttpClientFactory
汇集和重用,以减少资源消耗,只要HttpMessageHandler's
的生命周期没有过期。
阅读上述链接中的详细好处。
【讨论】:
是的,但是 IHttpClientFactories 本身不是为每个函数执行实例创建的吗?是否所有 IHttpClientFactories 都以线程安全的方式处理 HttpMessageHandler,或者是链接到每个 IHttpClientFactories 的 HttpMessageHandler 的唯一实例? 如何添加HttpClient
?通过-services.AddHttpClient();
?如果是这样,那么它不是作为单例实例注入的吗?
我通过 Startup.cs 添加它:services.AddHttpClient() - 是的。然后在函数类中,我注入一个 IHttpClientFactory 作为构造函数参数。然后我从函数内部的 _httpClientFactory.CreateClient() 获取 HttpClients,该函数具有 [ServiceBusTrigger](这可以在短时间内触发多次)。是否会为所有触发器执行共享 _httpClientFactory 对象?还是他们都有自己的 _httpClientFactory 对象?
从标题本身回答问题,IHttpClientFactory
默认注册为单例,所以工厂实例本身会被共享。
谢谢。我在其他地方读到它是暂时创建的,但我想情况并非如此。以上是关于通过 DI 注入到 ServiceBusTrigger Azure 函数中的 IHttpClientFactory 是不是为每个触发器重用或重新创建?的主要内容,如果未能解决你的问题,请参考以下文章