架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 270|回复: 4

[资料] ASP.NET Core(十五)使用 HttpClient 发送 HTTP 请求

[复制链接]
发表于 2022-5-14 19:37:21 | 显示全部楼层
使用ASP.NET构建应用程序时,使用HttpClient类的实例发出 HTTP 请求。使用 HttpClient 可能看起来很简单。但是,直到应用程序处于大负载下时,才会注意到一些潜在问题。

.NET 中提供的原始 HttpClient 类的相关问题:https://docs.microsoft.com/zh-cn/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests

HttpClient 虽然实现 IDisposable,但在 using 语句中声明和实例化它并非首选操作,因为释放 HttpClient 对象时,基础套接字不会立即释放,这可能会导致套接字耗尽问题。

问题实际上不是 HttpClient 本身,而是 HttpClient 的默认构造函数,因为它创建了一个新的实际 HttpMessageHandler 实例,该实例具有上面提到的“套接字耗尽”和 DNS 更改问题 。

QQ截图20220514191103.jpg

直接创建 HttpClient(错误使用)

直接实例化 HttpClient 对象,并且添加 using 保证调用 Dispose 方法,代码如下:

通过调用接口 5 次,使用 HttpClient 发送 HTTP 请求,通过如下命令查看网络连接:

可以看到当 HttpClient 释放后,本地电脑和目标服务器的连接为 TIME_WAIT 状态,并没有及时释放,在高并发情况下,会报错如下:

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.
QQ截图20220514191755.jpg

关于问题,也可以参考:

【译】错误地使用了 HttpClinet 会破坏您的软件
https://www.itsvse.com/thread-10310-1-1.html
使用 IHttpClientFactory 创建 HttpClinet(正确用法)

使用 DI 依赖注入 IHttpClientFactory 和 HttpClinet 是一样的,本文使用 IHttpClientFactory 创建 HttpClinet。

在 Startup 文件添加服务,代码如下:

HomeController 控制器代码如下:

我们通过调用接口同样使用 HttpClinet 发送 5 次请求,本机只和目标服务器建立了一个连接,在请求过程中,连接被复用了。如下图:

QQ截图20220514193101.jpg

IHttpClientFactory 将工厂创建的 HttpMessageHandler 实例汇集到池中,以减少资源消耗。 新建 HttpClient 实例时,可能会重用池中的 HttpMessageHandler 实例(如果生存期尚未到期的话)。

{
    "Lifetime": "Singleton",
    "ServiceType": "System.Net.Http.IHttpClientFactory",
    "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory"
  },
  {
    "Lifetime": "Singleton",
    "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory",
    "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory"
  }
IHttpClientFactory 默认实现为 DefaultHttpClientFactory,源码地址:https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpClientFactory.cs

通过在启用了 DI 的应用中使用 IHttpClientFactory,可避免:

  • 通过共用 HttpMessageHandler 实例,解决资源耗尽问题。
  • 通过定期循环 HttpMessageHandler 实例,解决 DNS 过时问题。


此外,还有其他方法使用生命周期长的 SocketsHttpHandler 实例来解决上述问题。

  • 在应用启动时创建 SocketsHttpHandler 的实例,并在应用的整个生命周期中使用它。
  • 根据 DNS 刷新时间,将 PooledConnectionLifetime 配置为适当的值。
  • 根据需要,使用 new HttpClient(handler, disposeHandler: false) 创建 HttpClient 实例。


上述方法使用 IHttpClientFactory 解决问题的类似方式解决资源管理问题。

  • SocketsHttpHandler 在 HttpClient 实例之间共享连接。 此共享可防止套接字耗尽。
  • SocketsHttpHandler 会根据 PooledConnectionLifetime 循环连接,避免出现 DNS 过时问题。


关于更多用法和配置,请参考:

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0
https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-6.0





上一篇:【译】错误地使用了 HttpClinet 会破坏您的软件
下一篇:【实战】jQuery Datatables 国际化插件
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 2022-5-14 19:38:14 | 显示全部楼层
回顾

ASP.NET Core(十四)基于 SkiaSharp 图片验证码
https://www.itsvse.com/thread-10287-1-1.html

ASP.NET Core(十三)判断是否是 Ajax 请求
https://www.itsvse.com/thread-10284-1-1.html

ASP.NET Core(十二)前端 JS、CSS 捆绑和压缩
https://www.itsvse.com/thread-10282-1-1.html

ASP.NET Core(十一)端点路由添加中间件显示所有 DI 服务
https://www.itsvse.com/thread-10269-1-1.html

ASP.NET Core(十)Configuration 配置优先级详解
https://www.itsvse.com/thread-10265-1-1.html

ASP.NET Core(九) 之 Middleware 中间件详解
https://www.itsvse.com/thread-9647-1-1.html

ASP.NET Core 中间件(Middleware)详解
https://www.itsvse.com/thread-8126-1-1.html

ASP.NET Core(八) 之 Swagger UI 默认参数的坑
https://www.itsvse.com/thread-9640-1-1.html

ASP.NET Core(七)深入刨析框架源码
https://www.itsvse.com/thread-9601-1-1.html

ASP.NET Core(六)DI 手动获取注入对象的方法
https://www.itsvse.com/thread-9595-1-1.html

ASP.NET Core(五)基于 CAP 分布式事务
https://www.itsvse.com/thread-9593-1-1.html

ASP.NET Core(四)之过滤器统一 ModelState 模型验证
https://www.itsvse.com/thread-9589-1-1.html

ASP.NET Core(三)使用 ActivatorUtilities 动态创建实例
https://www.itsvse.com/thread-9488-1-1.html

ASP.NET Core(二)通过代码自重启应用
https://www.itsvse.com/thread-9480-1-1.html

ASP.NET Core(一)使用 Redis 缓存
https://www.itsvse.com/thread-9393-1-1.html
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 2022-5-14 19:41:13 | 显示全部楼层
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2022-5-14 22:36:06 | 显示全部楼层
学习一下
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2022-5-19 09:45:12 | 显示全部楼层
来了来了,看看续集
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

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

Mail To:help@itsvse.com

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

GMT+8, 2022-7-6 05:10

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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