使用随手可得的工具,尽量少的前置要求,来完成任务。
0. 目录
- 1. 前言
- 2. 分析工具
- 2.1 基于Chrome DevTools 的Timing
- 2.1.1 关于Network标签页下的Timing部分
- 2.1.2 一些注意项
- 2.2 基于Curl 命令
- 3. 剩下的工作
1. 前言
对于业务开发选手而言,一般的功能性需求都不会是问题,所谓的"数据库套壳"操作。
而诸如系统性能,易用性等非功能性需求因为场景的问题,对于一般的业务开发选手而言,往往并没有多少实际的经验。
本文尝试提供一个起点,就是在没有多少性能调优经验时,如何起步 —— 首先从测量开始,毕竟"no measure,no improve"。
- 本文的主要受众是初次接触"HTTP请求性能调优"的同学。
- 因此这里不会介绍什么基于metrics的分析,相较于整体的理论介绍和实践,我们更关心的是业务场景下的快速解决问题。
- HTTP请求性能涉及到从最开始浏览器端发起的请求,中间途径的网络,后端的请求处理,以及最终返回给浏览器这一整条链路,导致问题的原因有很多,我们重点关注如何通过尽量简单的工具和操作,来缩小问题范围、最快地定位出导致问题的主要原因。
2. 分析工具
2.1 基于Chrome DevTools 的Timing
这里我们使用截取的一个样例进行示范:
先说结论: 以上请求响应的性能不及预期,主要瓶颈是在后端服务的处理上(“WATING(TTFB)”),接下来我们需要针对性对后端进行链路段的细化,以确定最终的桎梏点。
2.1.1 关于Network标签页下的Timing部分
在Chrome的DevTools工具中,Network标签页下的Timing部分提供了有关网络请求的详细时间信息。以下是Timing各个字段的解读:
Stage | Explain |
---|---|
Queueing | 1. “Queuing”(排队)是指网络请求在等待发送到服务器之前所处的状态。具体来说,当浏览器发送请求时,如果存在排队的请求或者请求队列已满,新的请求将进入"Queuing"状态,等待前面的请求完成或者队列空闲。 2. "Queuing"状态的时间是**"Blocked"时间的一部分**,表示请求在浏览器内核的请求队列中等待的时间。它通常反映了请求在发送给服务器之前由于资源限制而被阻塞的情况,例如并发连接数限制或请求队列已满。 3. 在性能分析中,"Queuing"状态的时间可以帮助您确定是否存在请求排队或请求队列限制的瓶颈。如果看到较长的"Queuing"时间,可能意味着请求队列过长或并发连接数设置过低,导致请求需要等待较长时间才能发送到服务器。您可以尝试优化并发连接数的配置或增加请求队列的容量,以改善请求的性能和响应时间。 注:Blocked时间: 请求发出时,等待在浏览器内核的请求队列中等待的时间(单位:毫秒)。 |
Stalled | 1. “Stalled”(阻塞)是指网络请求在等待可用的连接资源时所处的状态。具体来说,当浏览器尝试发起网络请求时,如果没有可用的连接资源(例如,无可用的连接池或达到了最大并发连接数),请求将进入"stalled"状态,并等待可用的连接资源。 2. "stalled"状态的时间是**"Blocked"时间的一部分**,表示请求在浏览器内核的请求队列中等待的时间。它通常反映了资源请求受限于可用连接资源的情况,可能由于网络延迟、连接池限制或其他因素导致。 3. 在分析性能问题时,"stalled"状态的时间可以帮助您确定是否存在连接资源的瓶颈,例如并发连接数设置过低或网络延迟较高等。您可以尝试优化连接资源的配置或调整并发连接数的限制,以改善请求的性能和响应时间。 4. 如果stalled过长,说明获取连接耗时长,如果用的是http/1.1可以升级到http2,合并请求,尽量减少请求数。 |
DNS Lookup | 进行DNS解析的时间,即将主机名解析为IP地址的时间(单位:毫秒) |
Initial connection | 建立TCP连接所花费的时间(单位:毫秒) |
Proxy negotiation | |
Request sent | 发送请求到服务器的时间,包括请求头和请求体的传输时间(单位:毫秒) |
ServiceWorker Preparation | |
Request to ServiceWorker | |
Waiting (TTFB) | 1. 关键指标 。 2. 这是指从请求发送完毕到接收到服务器返回的第一个字节所经过的时间,也称为"Time To First Byte"(单位:毫秒)。 3. 它表示了服务器响应的延迟时间,包括了网络延迟和服务器处理时间 4. 如果这一部分慢,说明服务器处理慢。 |
Content Download | 1. 关键指标 。 2. 这是指下载响应内容的时间。 3. 它包括了从接收到服务器响应的第一个字节到下载完整响应内容所花费的时间 4. 如果这个值超出预期,说明请求返回的内容很大,或者网络延迟比较明显,或者浏览器当前忙于处理其他任务 |
Receiving Push | HTTP2相关 |
Reading Push |
参考:
- Chrom官方文档 - timing-explanation
- chrome浏览器中的Timing详解 – 临时找的一篇,但解释得很清楚
2.1.2 一些注意项
- 注意Queueing Stage 对于最终请求耗时统计的影响,有的时候在DevTools下看到请求响应慢,可能并不是后端处理慢导致的,而是因为前端发起的请求过多(短时间内远超出"六个"的限制)等其他原因。排查问题的时候方向千万不能错。
如下面这个截图里, 绿色代表请求发出,灰色代表浏览器让该请求处于Blocked状态,还没有真正进入向后端发送(“Request sent”)阶段。
2.2 基于Curl 命令
除了直观地使用chrome devtools之外,另外一个方便使用就是curl命令了。(curl基本属于linux默认安装的命令,另外windows下也有相对应的第三方工具:curl -download)
以下代码我直接借鉴自下方给出的参考链接。为了避免抄袭之嫌,这里我只给出我个人认为需要额外说明的,更多的细节读者可以直接阅读对应的链接。
# 参考: https://www.zhihu.com/question/551074980/answer/3159565281
curl -o /dev/null -s -w '@curl-w.txt' https://www.zhihu.com
# 其中的 curl-w.txt 为预先创建的, 位于当前目录下:
DNS解析时长:%{time_namelookup}s\n
建立TCP时长:%{time_connect}s\n
请求到服务器响应时长:%{time_pretransfer}s\n
请求到服务器开始传输时长:%{time_starttransfer}s\n
总时长:%{time_total}s\n
上传速度:%{speed_upload} B/s\n
下载速度:%{speed_download} B/s\n
# 以上参数说明: ( 服务器处理耗时 = time_starttransfer - time_pretransfer )
time_namelookup DNS 域名解析的耗时
time_connect TCP 连接三次握手的时间
time_appconnect SSL/SSH 等上层协议建立连接的时间
time_redirect 所有重定向步骤所用的时间
time_pretransfer 请求开始到服务器响应的时间
time_starttransfer 请求开始到第一个字节将要传输的时间(包括预传输时间和服务器处理结果所需的时间)
time_total 请求总时间
参考:
- Chrom官方文档 - timing-explanation
3. 剩下的工作
正如开盘提及的,以上介绍的方法只能用于缩小导致问题原因的范围,比如是前端请求的问题,浏览器限制,亦或是网络问题,还是后端处理慢的问题等。
当问题被缩小后,我们还需要针对性地结合链路追踪或者补充日志记录,以及经验判断,来最终定位问题。
虽然本文里列举的方法无法帮助你最终定位问题,但因为其简单、便捷、学习门槛低的特性,可以显著降低你在面临问题时候的焦虑感,面对问题时候有所依凭。