放弃等待,故障到来:少一个 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 如果包含几十个图片标签,这些图片是以什么方式 ...
随机推荐
- CSS3画菱形和平行四边形以及立方体
利用CSS3中的transform属性画菱形和平行四边形 transform 实现2D或是3D的变形转换,通过transform可以实现对元素的四种变换:旋转.缩放.移动.倾斜 一.菱形 菱形的特点: ...
- CG-CTF | I wanna play CTF
这题跟bugku上的come_game超级像,于是菜狗决定研究一下,先鸣谢一下好友the fool,菜狗一直卡在开始界面哇,谢谢大佬给的第一关的数据 这是过到关卡1的数据,经过一系列的尝试得到结论: ...
- 170815-关于Session知识点
Cookie:实际上就是一个头. 服务器会创建Cookie,并且将Cookie以一个响应头的形式发送给浏览器 浏览器收到Cookie以后,会保存 ...
- bytesToSize
export function bytesToSize(bytes){ if (bytes === 0) return '0 B' let k = 1024, // or 1000 sizes = [ ...
- 《SQL Server 2012 T-SQL基础》读书笔记 - 2.单表查询
Chapter 2 Single-Table Queries GROUP BY之后的阶段的操作对象就是组(可以把一组想象成很多行组成的)了,HAVING负责过滤掉一些组.分组后的COUNT(*)表示每 ...
- JavaScript method overload
https://stackoverflow.com/questions/2187666/help-with-js-and-functions-parameters JavaScript doesn' ...
- React-Native 之 GD (六)无数据情况处理
1.还是网络问题,在网络出现问题或者无法加载数据的时候,一般我们会展示空白页,在空白页中提示 无数据 之类的提示,比较好的还会使用 指示器 的方式告诉用户网络出现问题等等. 这边我们做以下处理,当无数 ...
- Understanding ECMAScript 6 阅读问题小记
拖了一年说要看这本书,一直都没坚持下来,开个 bo 记录下觉得疑惑的问题,也算鞭策一下自己. 第一章 块级绑定 1. 第一章“块级绑定”下,说 const 变量如果绑定的是对象 Object,那么修改 ...
- Delphi XE2 之 FireMonkey 入门(22) - 数据绑定: BindingSource、BindingName、FindBinding()、Binding[]
在窗体上添加 TrackBar1.Edit1.Label1, 然后设置属性(可在设计时): procedure TForm1.FormCreate(Sender: TObject); begin ...
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_07 缓冲流_1_缓冲流的原理
一个字节一个字节的读取,先读取到a,a给到os操作系统.os再给JVM,.jVM再把a给java程序 读完a再读取b.这样一层层的返回,效率低下 一次读取,缓冲区数组返回来.