用于多个 API 服务的 .Net Core HttpClientFactory
.Net Core HttpClientFactory for Multiple API Services
我有一个 .Net Core 项目需要连接到大约 4 个不同的 API 服务,我不是任何 HttpClient 代码的专家,但据我发现,你是通常只想重用 HttpClient 的一个实例。据我所知,普遍的共识是在 .Net Core 中使用 HttpClientFactory,方法是在您的 Startup class 中注册它,然后使用 DI 请求它。
现在我的大部分默认值 headers 等等除了 BaseAddress url 之外都是相同的,当连接到 4 diff API 服务时我应该如何处理这个问题?我应该注册 4 个不同的命名客户端还是让一个客户端具有所有默认信息 pre-set 然后根据需要手动配置它,例如配置地址?
一般的问题是因为我对此很陌生,据说 re-use 一个 HttpClient 实例。
- 如果我为每个 API 服务创建 4 个不同的命名客户端,当我调用 .CreateClient() 方法时,这不会创建 4 个 HttpClient 实例吗?
- .CreateClient() 每次被调用时都会创建一个新实例,如果说我需要对一个 API 服务进行 3 次不同的调用,这是否会破坏拥有一个 HttpClient 实例的目的,这些调用中的每一个都将调用 .CreateClient() 来建立某种连接,这将创建 HttpClient 的 3 个实例?
如能提供清晰的帮助,我们将不胜感激,
谢谢!
使用IHttpClientFactory
的目的不是为了重用HttpClient
的实例。相反,它是重用(通过池化)HttpMessageHandler
(实际上是 HttpClientHandler
,派生自抽象 HttpMessageHandler
)的实例,它是管理 HTTP 连接和套接字的基础对象。 Microsoft Docs 中的 This diagram 显示得很好。
您担心频繁调用 IHttpClientFactory.CreateClient()
会产生与频繁调用 new HttpClient()
相同的问题。然而,这种情况并非如此。正如Microsoft docs所解释的那样,频繁调用new HttpClient()
会导致socket耗尽的原因是这个构造函数会创建一个新的HttpMessageHandler
实例:
However, the issue isn't really with HttpClient per se, but with the default constructor for HttpClient, because it creates a new concrete instance of HttpMessageHandler, which is the one that has sockets exhaustion and DNS changes issues mentioned above.
从IHttpClientFactory
的source code可以看出,它在CreateClient()
中没有使用HttpClient
的无参构造函数。相反,它从池中获取 HttpMessageHandler
并将其注入创建的 HttpClient
.
无论您使用的是类型化还是命名的客户端,都应该将 HttpClient 实例当作一个瞬态对象来使用:创建它的成本很低,并且您不需要长时间缓存它。
我有一个 .Net Core 项目需要连接到大约 4 个不同的 API 服务,我不是任何 HttpClient 代码的专家,但据我发现,你是通常只想重用 HttpClient 的一个实例。据我所知,普遍的共识是在 .Net Core 中使用 HttpClientFactory,方法是在您的 Startup class 中注册它,然后使用 DI 请求它。
现在我的大部分默认值 headers 等等除了 BaseAddress url 之外都是相同的,当连接到 4 diff API 服务时我应该如何处理这个问题?我应该注册 4 个不同的命名客户端还是让一个客户端具有所有默认信息 pre-set 然后根据需要手动配置它,例如配置地址?
一般的问题是因为我对此很陌生,据说 re-use 一个 HttpClient 实例。
- 如果我为每个 API 服务创建 4 个不同的命名客户端,当我调用 .CreateClient() 方法时,这不会创建 4 个 HttpClient 实例吗?
- .CreateClient() 每次被调用时都会创建一个新实例,如果说我需要对一个 API 服务进行 3 次不同的调用,这是否会破坏拥有一个 HttpClient 实例的目的,这些调用中的每一个都将调用 .CreateClient() 来建立某种连接,这将创建 HttpClient 的 3 个实例?
如能提供清晰的帮助,我们将不胜感激,
谢谢!
使用IHttpClientFactory
的目的不是为了重用HttpClient
的实例。相反,它是重用(通过池化)HttpMessageHandler
(实际上是 HttpClientHandler
,派生自抽象 HttpMessageHandler
)的实例,它是管理 HTTP 连接和套接字的基础对象。 Microsoft Docs 中的 This diagram 显示得很好。
您担心频繁调用 IHttpClientFactory.CreateClient()
会产生与频繁调用 new HttpClient()
相同的问题。然而,这种情况并非如此。正如Microsoft docs所解释的那样,频繁调用new HttpClient()
会导致socket耗尽的原因是这个构造函数会创建一个新的HttpMessageHandler
实例:
However, the issue isn't really with HttpClient per se, but with the default constructor for HttpClient, because it creates a new concrete instance of HttpMessageHandler, which is the one that has sockets exhaustion and DNS changes issues mentioned above.
从IHttpClientFactory
的source code可以看出,它在CreateClient()
中没有使用HttpClient
的无参构造函数。相反,它从池中获取 HttpMessageHandler
并将其注入创建的 HttpClient
.
无论您使用的是类型化还是命名的客户端,都应该将 HttpClient 实例当作一个瞬态对象来使用:创建它的成本很低,并且您不需要长时间缓存它。