Stalled:一次请求超时异常处理

简述

  最近项目中出现一个问题,前端每隔1秒向同一个url发起请求,第一次请求响应时间2秒左右,此后每次请求耗时会增加大约1秒,直到超时。

定位和验证

后台

  增加日志观察后台服务耗时情况,发现每次均耗时2秒左右,和前端第一次请求耗时差不多,后续也没有明显增长,基本可以排除后台服务的问题

浏览器

  首先是在项目指定的浏览器chrome上发现的问题,之后分别测试了edeg/firefox/ie,只在edeg上复现了问题,而edeg又是使用的Chromium内核,因此猜测是Chrome的某种机制导致的问题。

  打开chrome控制台,查看请求耗时的详情,如下:

    

  观察多次请求的耗时明细,发现真正发起请求到响应的时间依然稳定在2秒左右,这和后台观察到的情况是一样的。

  真正导致请求超时的是Connection Start:Stalled,这一项每次稳定增长1秒左右,最终导致超时。

  那么这个Stalled是何方神圣呢,chrome文档(https://developer.chrome.com/docs/devtools/network/reference/)如下:

  Here's more information about each of the phases you may see in the Timing tab:

  Queueing. The browser queues requests when:

  The browser is briefly allocating space in the disk cache    浏览器正在准备缓存

  There are already six TCP connections open for this origin, which is the limit. Applies to HTTP/1.0 and HTTP/1.1 only.  针对每个源,最多打开6个TCP连接

  There are higher priority requests.    有更高优先级的请求

  Stalled. The request could be stalled for any of the reasons described in Queueing.

  Stalled:在满足Queueing的任意一种条件时,请求将会停滞(阻塞)。

  更高优先级的请求此时并不存在,排除;TCP连接数量限制此时也未达上限,而且同网站的其他请求并未受影响,排除(对于TCP连接和数量限制后续可以再研究一下);

  同时在StackOverFlow上我找到一个类似的问题:https://stackoverflow.com/questions/27513994/chrome-stalls-when-making-multiple-requests-to-same-resource,其中一个回答如下:

  Yes, this behavior is due to Chrome locking the cache and waiting to see the result of one request before requesting the same resource again. The answer is to find a way to make the requests unique.

  I added a random number to the query string, and everything is working now.

  哈哈,完美契合缓存猜想,马上验证

    

验证1:在请求url上添加随机值

  将url由http://localhost:8080/master/timed修改为http://localhost:8080/master/timed?HxkNkz4Wwe

  结果:bingo!问题解决,所有请求并发进行,不再阻塞!    

  那么能不能通过后端的响应来解决问题呢?于是又做了一些验证

验证2:修改响应头,试图控制浏览器的缓存行为

  分别修改Cache-Control响应头的值为no-store/no-cache/no-store,no-cache/max-age=3, must-revalidate,观察

  结果:前面3种毫无反应;对于第4种,结果如下:

  

  没有缓存时,请求从后台获取数据,然后缓存到本地;有缓存时,请求直接从磁盘缓存获取数据,对于接口类的请求来说这有可能获取到过期的数据,显然是不可接受的,事实上,一般之后资源类的数据(js/css/图片等)才会通过缓存获取。

 结论

在拿到响应之前,chrome会将资源(以url表示)相关的缓存锁住,后续所有相同的url请求都必须在队列中等待,直到前面的请求及缓存处理完之后才能依次进行。

要解决这个问题,只要每次请求时在链接上加个随机值就好了。

转自:Stalled:一次请求超时异常处理 - 码农教程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值