架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2566|回复: 4

[资料] 【译】错误地使用了 HttpClient 会破坏您的软件

[复制链接]
发表于 2022-5-14 17:11:56 | 显示全部楼层 |阅读模式
多年来,我一直错误地使用 HttpClient,但它最终噩梦还是到来了。我的网站不稳定,我的客户非常愤怒,通过一个简单的修复,性能大大提高,不稳定性得以消除。

QQ截图20220514170012.jpg

同时,我实际上通过更有效的套接字使用提高了应用程序的性能。

微服务可能是一个难以处理的问题。随着更多服务的添加和单体应用的分解,服务之间的通信路径往往会越来越多。有许多通信选项,但 HTTP 是一个非常流行的选项。如果微服务是用 C# 或任何 .NET 语言构建的,那么您很可能已经使用了 HttpClient。


问题所在

该using语句是处理一次性对象的 C# 特性。一旦using块完成,那么一次性对象(在这种情况下HttpClient)就会超出范围并被处置。调用该dispose方法并清理正在使用的任何资源。这是 .NET 中非常典型的模式,我们将它用于从数据库连接到流编写器的所有内容。实际上,任何具有必须清理的外部资源的对象都使用该IDisposable接口。

而且你不能因为想用 using 来包装它而受到责备。首先,这样做被认为是一种很好的做法。事实上,微软的官方文档 using:


通常,当使用IDisposable对象时,应该在using语句中声明并实例化它。
其次,您可能已经看到的所有代码...... 的开始HttpClient都会告诉您使用using语句块,包括ASP.NET 站点本身的最新文档。网上的文章也是这么说。

但HttpClient不一样。虽然它实现了IDisposable接口,但它实际上是一个共享对象。这意味着在幕后它是可重入和线程安全的。您应该在应用程序的整个生命周期内HttpClient共享一个实例,而不是为每次执行创建一个新实例。HttpClient让我们看看为什么。

你自己看看吧

这是一个简单的程序,用于演示HttpClient:

这将向  http://aspnetmonsters.com 打开 10 个请求并执行GET,我们只是打印状态代码,所以我们知道它正在工作。输出将是:

等等,还有更多!

所有的工作和一切都对这个世界是正确的。除了它不是。如果我们拔出netstat工具并查看运行它的机器上的套接字状态,我们将看到:

C:\code\socket>NETSTAT.EXE
...
  Proto  Local Address          Foreign Address        State
  TCP    10.211.55.6:12050      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12051      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12053      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12054      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12055      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12056      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12057      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12058      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12059      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12060      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12061      waws-prod-bay-017:http  TIME_WAIT
  TCP    10.211.55.6:12062      waws-prod-bay-017:http  TIME_WAIT
  TCP    127.0.0.1:1695         SIMONTIMMS742B:1696    ESTABLISHED
...
嗯,这很奇怪……应用程序已经退出,但仍然有一堆这样的连接打开到托管 ASP.NET Monsters 网站的 Azure 机器。它们处于TIME_WAIT状态,这意味着连接已在一侧(我们的)关闭,但我们仍在等待查看是否有任何其他数据包进入,因为它们可能已在某处的网络上延迟。下面是 TCP/IP 状态图:

QQ截图20220514170814.jpg

Windows 将在此状态下保持连接 240 秒(由 设置[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay])。Windows 打开新套接字的速度是有限制的,所以如果你用尽了连接池,那么你可能会看到如下错误:

Unable to connect to the remote server
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
在谷歌中搜索它会给你一些关于减少连接超时的糟糕建议。事实上,当正确使用HttpClient或类似构造的应用程序在服务器上运行时,减少超时可能会导致其他不利后果。我们需要理解“正确”的含义并解决根本问题,而不是修补机器级别的变量。

修复它

如果我们共享一个实例,HttpClient那么我们可以通过重用它们来减少套接字的浪费:

HttpClient请注意,对于整个应用程序,我们只有一个 shared 实例。HttpClient 仍然像以前一样工作(实际上由于套接字重用而快一点)。Netstat 现在只显示:

TCP    10.211.55.6:12254      waws-prod-bay-017:http  ESTABLISHED
在生产场景中,我的套接字数量平均在 4000 个左右,峰值会超过 5000 个,有效地挤压服务器上的可用资源,从而导致服务崩溃。实施更改后,使用中的套接字从平均超过 4000 个下降到始终少于 400 个,通常在 100 个左右。

这是来自我们的监控工具的图表的一部分,显示了在我们将有限的修复证明部署到选定数量的微服务后发生的情况。


QQ截图20220514171036.jpg

这是戏剧性的。如果你有任何类型的负载,你需要记住这两件事:

让你的HttpClient静态。
除非您明确地寻找特定行为(例如导致您的服务失败),否则不要丢弃或包装您的使用。HttpClient


总结

我们几个月来一直在努力解决的套接字耗尽问题消失了,我们的客户进行了一次虚拟游行。我不能低估这个错误是多么不明显。多年来,我们习惯于处理实现的对象,IDisposable并且许多重构工具(如 R# 和 CodeRush)实际上会在您不这样做时发出警告。在这种情况下,处置HttpClient是错误的做法。HttpClient实施IDisposable和鼓励错误行为是不幸的

原文:https://www.aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/




上一篇:ASP.NET Core 在 IIS 中 In-Process 和 Out-Of-Process 托管模型
下一篇:ASP.NET Core(十五)使用 HttpClient 发送 HTTP 请求
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 2022-5-14 17:25:22 | 显示全部楼层
TCP TIME_WAIT 是一个正常的 TCP 协议操作,它意味着在传递最后一个 FIN-ACK 之后,客户端将等待双倍最大段寿命 (MSL) 时间过去,以确保远程 TCP 收到其连接终止请求的确认。默认情况下,MSL 为 2 分钟。最多可以在 TIME_WAIT 中停留 4 分钟,称为两个 MSL。

https://docs.microsoft.com/en-us ... t-from-netstat.html
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2022-5-14 22:35:22 | 显示全部楼层
学习学习
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2022-5-19 09:39:05 | 显示全部楼层
明明都是中文,可连成句子我就看不懂了
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 2023-11-6 07:16:05 | 显示全部楼层
test
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2024-4-27 05:19

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表