关于【浏览器请求最大并发数】的debug之旅


又到了三月,处于一些众所周知的原因。把之前没有完成的文章往出放一放,增加一些大家对我的了解。

问题背景

有一天被pm小姐姐反馈网站无法打开,一直是白屏; 我再本地打开了一下是正常的,而且展示速度也是正常的;查了下日志报错也没有啥问题;这个页面中只有一个展示二维码,扫码登录的功能;

于是开始了我的debug之旅:

收集了报错现场 ---小姐姐的错误请求的curl以及截图;发现请求一直pending,直到30s之后才会正常返回,于是排除了网络导致的请求延迟之后,开始考虑是什么因素致使请求一直被挂起呢?

收集的请求

30s后返回

分析了一下每个请求的 Timing之后发现:每个请求的Stalled时间都很久,但是又都可以发送成功。

image.png

所以要了解一下Timing之中各个参数的意义,这个参数其实在优化网络请求时我们也有了解过,顺手做一下复习:

Queuing - 资源加载的排队

Stalled/Blocking - 请求等待发送所用的时间。Queuing中的所有原因加上代理协商所用的任何时间。

Proxy Negotiation - 与代理服务器连接协商所用的时间。

DNS Lookup - DNS查询所用的时间

Initial Connection / Connecting - 建立连接所用的时间,包括TCP 握手/重试和协商 SSL的时间。

SSL - 完成SSL握手所用的时间。

Request Sent / Sending - 发出网络请求所用的时间。通常不到一毫秒。

Waiting (TTFB) - 等待初始响应所用的时间,也称为至第一字节的时间。

Content Download / Downloading - 接收响应数据所用的时间。

画一画重点 请求等待发送所用的时间。Queuing中的所有原因加上代理协商所用的任何时间。

在查看我的请求为何被挂起的过程中,突然发现我的请求优先级是medium ,话说会不会是被更高优先级的请求摆了一道呢?

在 关于请求被挂起页面加载缓慢问题的追查 这篇文章中了解到,chrome有cache_lock的机制,并且可以通过查看chrome 网络日志的方式来查看,并且在其中可以查看请求的优先级;

于是NetLog 粉墨登场

浏览器输入 chrome://net-export/ 打开 Chrome NetLog ,按照步骤收集,对应时间的网络日志;并且下载到本地;

NetLog

在 NetLog Viewer,上传刚才下载好的网络日志(不排除可以肉眼看出日志中想要的内容的可能,我试了一下,失败了)。

NetLog Viewer

上传完成状态

点击左侧的Event,然后按需搜索就好了。在这里我看到了我心仪已久的priority,发现似乎请求集美们都是medium,没有人比对应的请求更优秀。( 走偏

但是不太影响我们在网络日志中发现了所有请求的对应状态,麻麻再也不怕别人问我请求中状态变化了。( 怕

priority

意识到可能不是这个原因,还是花了点时间搞清楚了 https://juejin.im/post/5c7cc63951882562e7482c65

虽然在网络日志这里没有解决问题,但是还是发现了一个重要的表象 ---- 校验二维码的请求怎么会这么多? ( 列文虎克

校验请求

震惊的发现在浏览器的其他tab下,打开了一个闲置的登录页面,失控了一样发送校验请求。关掉之后,本页面的登录、加载也回归了正常。(如此,我们也抓到了本次bug的真凶!)可是真凶的成因不在本篇文章的了解范围内,按下不表了。( 已手刃

探究下为什么会出现这个情况?

排除代码中的bug本身,造成这个现象的原因其实是因为浏览器对同一域名请求是有最大并发数限制的。正是因为疯狂发起的请求超过了请求阈值,并且这个检查接口本身返回就比较慢,造成了后续请求的挂起而不是直接失败。

不同浏览器对并发限制也不尽相同:

各浏览器并发统计

究其原因是处于多方面因素的优化考量:

对客户端操作系统而言,过多的并发涉及到端口数量和线程切换开销。

HTTP/1.1有Keep Alive,支持复用现有连接,等请求返回回来后,再复用连接请求可以快很多。

将所有请求一起发给服务器,也很可能会引发服务器的并发阈值控制而被BAN。

同样涉及到的优化方式也比较多:

domain hash:对资源做哈希,请求到不同的域下面。关于域名发散与收敛,其实要对不同场景分别做细化了。

cookie free:前后端分离,减少不必要的cookie提交。

css sprite:将零星的图片整合到一张大图中,减少请求次数。

js/css combine:资源合并,减少请求次数,不过也会增加文件修改的几率。

max expires time:合理设置客户端缓存时间。

loading images on demand:图片按需加载。

夹带一些这方面的面试题附送给各位:

https://juejin.im/post/5d59ffe46fb9a06ad0056ddf

以上。

参考链接:

https://segmentfault.com/a/1190000015133004

https://developers.google.com/web/tools/chrome-devtools/network/understanding-resource-timing?hl=zh-cn

https://blog.csdn.net/zhang_zhenwei/article/details/90692095

https://www.cnblogs.com/sunsky303/p/8862128.html

https://www.zhihu.com/question/20474326

http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/


本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):