放弃等待,故障到来:少一个 await 引发的 tcp 连接泄漏故障
更新:后来升级至 .NET Core 2.2 Preview 3 ,并将 System.Net.Http 升级至 4.3.4 之后没出现这个问题,问题与 https://github.com/dotnet/corefx/pull/32568 有关。
以下内容是当时的错误判断。
今天上午的故障之后,我们 review 了代码,通过压力测试重现问题,分析验证,最终找到了问题的真正原因 —— 在 ASP.NET Core 程序中调用 async 方法时没加 await 。
public async Task<IActionResult> GetRecommDocuments()
{
//...
ShowItem(docs, app); //async方法,其中用到了HttpClient
return Ok(docs);
}
就是上面的代码中“漏”写了 await ,不是粗心漏写,是故意为之。我们不关心调用 ShowItem 的结果,只要能执行就行,即使执行失败也可以接受。不加 await 可以让 GetRecommDocuments 方法调用 ShowItem 之后无需等待继续执行从而提高响应速度,但是没想到这一招偷工减料,竟然抽空了服务器的 TCP 连接资源,让整个服务器大厦轰然倒塌。
以下删除线部分的分析是错误的,真正原因有待进一步追踪。
开始从 async/await 的角度怎么也想不通 —— 少一个 await 怎么会如此严重后果,后来突然想到罪魁祸首不在 async/await 而在依赖注入(DI)。GetRecommDocuments 中的 HttpClient 实例是通过构造函数的 IHttpClientFactory 注入的,注入的 HttpClient 实例的生命周期是 Scoped (当前请求范围),本来正常情况下一个请求处理结束,HttpClient 实例会被 DI 容器 Dispose,所使用的 Socket 连接会被放回连接池,但是由于没加 await ,让 ShowItem 不走正常路,DI 容器在请求处理结束时跟踪不到 ShowItem 中的 HttpClient 实例,也就不会进行 Dispose 。结果来一个请求,IHttpClientFactory 就创建一个 HttpClient 实例,每个 HttpClient 实例都占用一个新的 TCP 连接,直至拖垮服务器。
随着软件开发技术的发展,开发效率越来越高了,要写的代码越来越少了,但要考虑的问题却越来越多了。虽然我们每天都在用着 .NET Core ,但由于其内部工作机制不够熟悉,原以为“巧夺天工”的一招却酿成大错,我们会牢记这次教训,进一步地对 .NET Core 刨根问底 。
放弃等待,故障到来:少一个 await 引发的 tcp 连接泄漏故障的更多相关文章
- 一个人也可以建立 TCP 连接呢
今天(恰巧是今天)看到有人在 SegmentFault 上问「TCP server 为什么一个端口可以建立多个连接?」.提问者认为 client 端就不能使用相同的本地端口了.理论上来说,确定一条链路 ...
- 第二篇:一个经典的比喻( 关于TCP连接API )
前言 编程是对现实世界的模拟,网络通信自然也是对现实世界通信的模拟.可以将网络通信中使用的各种API和对现实世界中的各种通信设备进行通讯的操作进行对比以加深理解. 对比 socket() 函数 vs ...
- 一个经典的比喻( 关于TCP连接API )
前言 编程是对现实世界的模拟,网络通信自然也是对现实世界通信的模拟.可以将网络通信中使用的各种API和对现实世界中的各种通信设备进行通讯的操作进行对比以加深理解. 对比 socket() 函数 vs ...
- 可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?
本文由原作者松若章原创发布,作者主页:zhihu.com/people/hrsonion/posts,感谢原作者的无私分享. 1.引言 一道经典的面试题是:从 URL 在浏览器被被输入到页面展现的过程 ...
- 夺命连环问:一个 TCP 连接可以发多少个 HTTP 请求?
曾经有这么一道面试题:从 URL 在浏览器被被输入到页面展现的过程中发生了什么? 相信大多数准备过的同学都能回答出来,但是如果继续问:收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式.什 ...
- 一个 TCP 连接可以发多少个 HTTP 请求?
曾经有这么一道经典面试题:从 URL 在浏览器被被输入到页面展现的过程中发生了什么?相信大多数准备过的同学都能回答出来,但是如果继续问:收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式. ...
- 懵圈了,面试官问一个 TCP 连接可发多少个 HTTP 请求?
作者:松若章 https://zhuanlan.zhihu.com/p/61423830 一道经典的面试题是从 URL 在浏览器被被输入到页面展现的过程中发生了什么,大多数回答都是说请求响应之后 DO ...
- 一个tcp连接可以发多少http请求
-----来自:松若章 -----zhuanlan.zhihu.com/p/61423830 曾经有这么一道经典面试题:从 URL 在浏览器被被输入到页面展现的过程中发生了什么?相信大多数准备过的同学 ...
- 面试官:一个 TCP 连接可以发多少个 HTTP 请求?
曾经有这么一道面试题:从 URL 在浏览器被被输入到页面展现的过程中发生了什么? 相信大多数准备过的同学都能回答出来,但是如果继续问:收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式 ...
随机推荐
- LeetCode--146--LRU缓存机制(python)
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果密钥 (key) 存 ...
- appium环境666
一.安装JDK,配置JDK环境 appium下载地址: https://github.com/appium/appium-desktop/releases/ 百度搜索下载就行,这里分享一个下载链 ...
- postman—UI测试
思路 发送请求去拿到网站的响应->html 解析HTML标签,判断一些元素是否显示 目的 快速检查UI是否正确 测试地址 http://www.itest.info/courses 我们接下来要 ...
- div拖拽到iframe上方 导致 缩放和拖拽的不平滑和鼠标事件未放开 解决方法
思路一:用在开始进行缩放(触发了resizable的start事件)为iframe添加z-index属性,将iframe放置在最下层. $("#draggable").resiza ...
- asp.net 怎么上传文件夹啊,不传压缩包
最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...
- MongoDB可视化工具的安装
MongoDBCompass MongoDB Compass是一款优秀可靠的mongodb可视化数据库管理软件.可以更加方便地与mongodb数据库进行交互,支持对数据库进行查询.分析或者查看数据库的 ...
- iOS9 3DTouch 之 Home Screen Quick Actions
最后更新:2016-12-18 测试环境: Xcode8.1 一.前言 iOS9 已经过去一年了,3D Touch也在项目中实战过,但一直没有总结一下,现在新的项目也用到了3D Touch, 网上找了 ...
- HTML5和CSS3兼容清单
1.CSS3 2.CSS3选择器 3.HTML5 4.HTML5 From
- MSSQL 如何导出db所有用户权限创建语句
use dbgoDECLARE @Database varchar(255),@loginName varchar(255),@roleName varchar(255),@sql nvarchar( ...
- MySQL的性能指标计算和优化方法
MySQL的性能指标计算和优化方法1 QPS计算(每秒查询数) 针对MyISAM引擎为主的DB mysql> show global status like 'questions';+----- ...