在 ASP.NET Core 应用程序中使用多个 HttpClient 对象



当有多个客户端(公司)使用 ASP.NET 核心应用程序并且必须在每个公司的应用程序中维护具有相应客户端证书 ASP.NET 单独的 HttpClient 实例时,最好的应用程序设计是什么?

首先,关于应用程序的一些重要事实:

  • 这是一个 ASP.NET 核心3.1应用程序。
  • 使用此 ASP.NET 核心应用程序的每家公司首先需要上传自己的客户端证书 在注册期间。证书和相应的密码是 存储在数据库中。证书是通信所必需的 使用某些必须代表 该公司在 提到 ASP.NET 核心应用程序。换句话说,对于某些操作 公司在 ASP.NET 核心应用程序,一些外部网站执行 必须通过 POST 方法和相应的机构通知服务,并且 必须处理并返回其响应。
  • 注册后, 公司可以开始向上述 ASP.NET 核心发送请求 应用。此 ASP.NET 核心应用程序应获得 从数据库中创建相应的公司证书 HttpClient 对象并向其添加证书,准备请求数据并调用外部 Web 服务 通知。那么来自这个外部 Web 服务的响应应该是 处理并作为对原始公司请求的响应返回。
  • 当然,可以同时有来自不同公司的请求
  • ,但也可能有来自不同公司办公室的同一公司同时请求 - 来自同一公司的所有请求都使用相同的公司客户端证书,但通知外部 Web 服务的请求数据(正文)将始终不同。

据我所知,每次调用外部 Web 服务时创建新的 HttpClient 对象并不是最佳做法。我已经考虑过HttpClientFactory,但在我的情况下,每个HttpClient对象都必须包含公司的相应客户端证书。我知道 ASP.NET Core支持名为HttpClient为每个公司维护单独的HttpClient,但是AFAIK这个命名客户端只能在Startup类中创建。这还不够,因为可以在应用程序运行时随时注册新公司 ASP.NET 公司,公司可以在应用程序运行时上传新证书,从而使现有的命名客户端无效等。

我正在考虑维护一个静态列表,其中包含每个公司的一个 HttpClient 对象。当对公司的第一个请求启动时,将使用相应的客户端证书创建新的 HttpClient 并将其添加到此列表中。对于来自同一公司(或办公室)的所有后续请求,从上述静态列表中获取相应的 HttpClient 并重复使用。当然,我必须在公司的 HttpClient 实例上建立一些锁定,以便在来自同一公司的同时请求时它不会中断。我对这种设计的一个担忧是,可能有几百家公司,这个http客户端列表可能很长。

您还有其他想法或建议吗?

我正在考虑维护一个静态列表,其中包含每个公司的一个 HttpClient 对象。

在高层次上,我认为每个公司的单个实例是正确的方法,但魔鬼在于(实施)细节。

当然,我必须建立一些锁定。

如果您使用的是为此类用法而构建的类型,则不会。ConcurrentDictionary,特别是它的GetOrAdd方法,将为您提供一种键控存储机制,其中项目是懒惰创建的,并且是线程安全和无锁的。

我对这种设计的一个担忧是,可能有几百家公司,这个http客户端列表可能很长。

我不知道是否有一个特定的数字需要你开始担心(我相信取决于操作系统和硬件),但至少根据使 HttpClient 单例建议闻名的文章,它是数千,而不是数百。

"在生产场景中,我的套接字数量平均约为 4000 个,高峰期将超过 5000 个,这有效地压垮了服务器上的可用资源,从而导致服务崩溃。实施更改后,使用的套接字从平均超过 4000 个下降到始终低于 400 个,通常在 100 个左右。

不过,如果这是一个问题,您可以做的一件事来缓解它,那就是允许那些缓存的HttpClient实例偶尔过期。(这也应该减轻另一个著名的问题。不幸的是,ConcurrentDictionary并没有提供开箱即用的功能。MemoryCache可以,但不直接支持像ConcurrentDictionary这样的惰GetOrAdd语义。为了两全其美,看看LazyCache。

最新更新