tsy77 / blog

78 stars 2 forks source link

关于请求被挂起的问题排查 #18

Open tsy77 opened 5 years ago

tsy77 commented 5 years ago

起因

起因是公司的某MIS系统中某个HTTP请求耗时长,有时达到几十秒,导致了xhr出发了onTimeout事件;chrome的network面板中,发现请求一直在stalled阶段。

可能的原因

Stalled/Blocking的解释如下:

Time the request spent waiting before it could be sent. This time is inclusive of any time spent in proxy negotiation. Additionally, this time will include when the browser is waiting for an already established connection to become available for re-use, obeying Chrome's maximum six TCP connection per origin rule.

通过上面的描述,我们知道Stalled/Blocking其实是建立连接前的时间,其中包括了代理协商、等待socket复用的时间。

我们推测可能又如下原因:

排查

排除同源请求过多

我们去掉了同源下的大部分请求,仍在存在超时问题,说明同源请求多不是关键因素。

Wireshark抓包

随即想到用Wireshark抓下包,看下TCP的包的传输情况,但此case是偶现,并且可操作该后台(有机会复现)的同学散布在全国各地,并且是非研发,远程帮助他们装wireshark成本较高,作为备选项。

日志探究

接着想到了chrome日志(比network面板内容详细太多),随即让操作同学打开chrome日志,出现问题后,将日志发给我。

得到的错误日志如下: dbe005c582579b65a9be2a33ee937c06

我们可以看到实际的状态处于IO_PENDING,load_state处于WAITING_FOR_RESPONSE

看到这里我们大概明白了,应该是在代理协商阶段,服务一直没有响应,导致了超时。超时时间设置的40s,也与日志吻合。

Chromium 源码

好奇这两个状态,于是看了下chromium源码:

从注释中可以看出,WAITING_FOR_RESPONSE代表着请求发出但是没有接到响应头的状态。

IO_PENDING比较宽泛,请求发出到未完成都属于IO_PENDING

chrome日志怎么看

其中+代表动作开始,-代表结束,--->代表动作的状态。

我们可以看出一个完整请求首先去域名解析(host resolve),接着去做socket连接

aloha-zzz commented 4 years ago

hello , 请问最重要怎么解决呢