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

发布时间:2022-07-02 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Stalled:一次请求超时异常处理脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

简述

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

定位和验证

  • 后台

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

  • 浏览器

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

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

    

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

    观察多次请求的耗时明细,发现真正发起请求到响应的时间依然稳定在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:
      •   There are higher priority requests.    有更高优先级的请求
      •   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连接
      •   The browser is briefly allocating space in the disk cache    浏览器正在准备缓存
    •   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种,结果如下:

    

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

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

 结论

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

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

Tips

这次解决这个问题花的时间稍微有点长,原因是一开始的方向有误,直接去翻后台代码和脚本浪费了不少时间和精力。

正确的做法是首先确定问题发生在哪里:前端还是后端,如果是后端的话再看是服务器还是服务本身(老二分法了),确定是服务本身之后再去看细节,不花无谓的时间。

 

 

 

 

脚本宝典总结

以上是脚本宝典为你收集整理的Stalled:一次请求超时异常处理全部内容,希望文章能够帮你解决Stalled:一次请求超时异常处理所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:并发