【问题标题】:HttpClient shared instance with different sessions具有不同会话的 HttpClient 共享实例
【发布时间】:2018-02-01 11:31:03
【问题描述】:

上下文

使用HttpClient 的推荐方法是创建一个实例并共享它(根据Microsoft 文档)。有很多例子表明每个请求(在服务器上)使用 HttpClient 会产生问题。

问题

在我的情况下,我必须同时运行多达 20 个不能相互干扰的“会话”。 “会话”是指对一个服务或多个服务的独立操作集。不应在这些会话之间共享任何数据,尤其是在 cookie 之间。

这些会话是持久的会话(可以持续数天)。但同时最多只能有 20 个并发会话。实例化这些会话时启动缓慢是可以接受的(最多 5 秒)。

问题

我应该使用游泳池吗?我应该重复使用相同的HttpClient 实例吗?我应该最多生成 20 个HttpClients 吗?此外,考虑到它们同时运行,假设对单个HttpClient 的并发调用将被阻塞是否正确?

【问题讨论】:

  • 这取决于你的服务器在做什么。如果它没有为其他应用程序使用大量的 TCP 连接,那么 20 个 HttpClient 实例,每个都有一个会话。
  • @Crowcoder 它是一个 GraphQL API 服务器,因此它将接收大量通过 ASP.NET Core 2 处理的 HTTP POST 请求。
  • 然后我会尝试使用单个客户端,但通过HttpRequestMessage 改变请求,而不是在客户端本身上设置任何属性。 See my blog 接收者。
  • @Crowcoder 通过使用单个实例,我实际上可以并行使用客户端,还是会阻塞直到另一个会话完成上一个请求?
  • 它不会阻塞,它被设计为多线程访问。只是不要通过在任何调用中添加.Result.Wait() 来阻止自己,一切都应该完全异步。

标签: c# asp.net asp.net-core concurrency httpclient


【解决方案1】:

建议只创建HttpClient 的单个实例,因为它会创建一个持续一段时间的 TCP 连接。最终,它会自然地收集或关闭垃圾,但与此同时,您可能会耗尽服务器上打开的最大连接数。每个连接还有一些资源利用率,在堆叠时可能会出现问题。

但是,这是没有硬性规定的事情之一。某些事情,比如为每个操作创建一个新的HttpClient,显然是有问题的,但通常每个对服务器的请求(不是通过HttpClient 发送的每个请求)一个实例不应该有问题,除非您服务于大量并发请求。

您也可以在您的应用程序中将其设为单例。 HttpClient 在技术上不是用户或会话特定的东西。如果您更改的默认标头不应跨会话泄漏,这只会有问题。例如,您希望在创建请求时附加 Authorization 之类的标头,而不是在设置客户端时作为默认标头。只要您对如何使用它很聪明,共享它就没有问题。不过,“聪明地使用它”有时可能是一个失败点。即使你是,下一个开发者也会是。更重要的是,他们甚至会知道自己应该吗?你甚至可能会忘记自己。

就个人而言,我会开始将其设置为请求范围,其中对您的 Web 应用程序的每个请求都会获得一个单独的实例,但在该请求期间,同一实例将用于所有带有 HttpClient 的操作。然后,您可以进行一些分析以查看服务器如何处理此问题,如果确实出现问题,则可以寻找替代解决方案。

【讨论】:

  • 每个请求甚至都不是一个实例。每个作业只有一个实例。我的 api 允许用户指定可以运行数天的作业。作业的开始和停止很少发生,并且在任何给定时间最多有 20 个并发作业。因此,HttpClient 将被实例化一次并在多个小时内多次使用,直到它完成工作或用户停止它。
  • 所以使用方面会少很多。
猜你喜欢
  • 1970-01-01
  • 2014-11-24
  • 2011-06-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 2020-10-29
  • 1970-01-01
  • 2012-06-28
相关资源
最近更新 更多