通过 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 是不是为每个触发器重用或重新创建?的主要内容,如果未能解决你的问题,请参考以下文章

依赖注入[4]: 创建一个简易版的DI框架[上篇]

依赖注入[4]: 创建一个简易版的DI框架[上篇]

大话设计模式--DI(依赖注入)

ASP.NET Core中的依赖注入:依赖注入(DI)

spring------控制反转(IOC)/依赖注入(DI)

Spring总结三:DI(依赖注入)