如何查看HTTP请求耗时

1 篇文章 1 订阅
1 篇文章 0 订阅

HTTP 请求流程

一次完整的 HTTP 请求流程主要包括以下几个阶段:

域名解析

当 HTTP 请求的是域名时,需要先进行域名解析,将域名转换为 IP 地址后再进行网络连接。

域名解析的流程涉及查询操作系统 DNS 缓存、请求外部 DNS 服务器解析等,最终得到域名对应的 IP 地址。

建立 TCP 连接

当客户端拿到目标的 IP 地址后,就向目标发起建立 TCP 连接的请求,即 TCP 的三次握手,结束后即完成了 TCP 连接的建立。

建立 SSL/TLS 连接

当请求的协议是 HTTPS 时,需要先与目标建立 SSL/TLS 连接,通过获得的秘钥对后续的通信消息进行加密。

发送 HTTP 消息

发送具体的 HTTP 请求消息体,等待目标服务器返回。

服务器响应并返回

发送具体的 HTTP 请求消息体,等待目标服务器返回。

当我们在实际业务中发现某个 HTTP 请求响应非常慢时,就需要分析是上述哪个阶段的耗时较长,本文介绍两种方式来查看 HTTP 请求流程中各个阶段的耗时情况。

Node.js 查看请求耗时

事件 Event

在 Node.js 中,一个 http 请求的各个阶段是通过事件来定义的,即到达某个阶段后就会抛出对应的时间,我们可以通过监听这些事件,然后进行逻辑处理,从而实现统计各个阶段的耗时。

相关事件及对应的模块如下:

阶段事件模块触发时机
创建一个 socket 对象sockethttp.ClientRequest当一个 socket 对象被分配给当前 request 对象之后
域名解析lookupnet.Socket完成域名解析之后,建立连接之前
建立 TCP 连接connectnet.Socket当 socket 连接建立完成之后
建立 TLS 连接secureConnecttls.TLSSocketTLS 连接握手完成之后
服务器开始返回消息readablestream.Readable当 response 中的数据可读时
服务器返回数据datastream.Readable当 response 中有一块数据可以被读取时
服务器完成返回endstream.Readable当 response 中没有数据可被读取时

一个例子:app.js

request 模块

request 模块已经提供了成熟的统计 HTTP 请求耗时的功能,只需要在 options 中配置 time 字段为 true 即可:

const request = require('request');

const url = 'https://www.baidu.com';
const options = {
  url, method: 'GET', time: true,
};
request(options, (error, response) => {
  if (error) {
    console.error(error);
  }
  console.log(response.timings);
  console.log(response.timingPhases);
});

输出结果如下:

{ socket: 34.420195999999976,
  lookup: 47.29232500000006,
  connect: 63.71983800000004,
  response: 128.208279,
  end: 131.76554800000002 }
{ wait: 34.420195999999976,
  dns: 12.872129000000086,
  tcp: 16.427512999999976,
  firstByte: 64.48844099999997,
  download: 3.5572690000000193,
  total: 131.76554800000002 }

可以看到,response.timings 统计了各个阶段的时间戳,response.timingPhases 统计了各个阶段的耗时。

注意:低版本的 request 模块可能不具备该功能。

curl 查看请求耗时

curl 指令是一个功能非常强大的指令,也可以统计 HTTP 请求各个阶段的耗时,使用如下:

curl -o /dev/null -s -w "time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\ntime_appconnect: %{time_appconnect}\ntime_redirect: %{time_redirect}\ntime_pretransfer: %{time_pretransfer}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" "https://www.baidu.com"

参数解析:

  • -o /dev/null 把返回值丢掉,不用输出
  • -s 静默输出,不输出进度条
  • -w 按指定格式打印信息,其中包含一些特定的参数:
    • time_namelookup:从开始到域名解析完成时的耗时
    • time_connect:从开始到 TCP 连接建立完成的耗时
    • time_appconnect:从开始到 TLS 连接建立完成的耗时
    • time_redirect:多次重定向(如果有)的耗时
    • time_pretransfer:从开始到准备发送请求消息前的耗时
    • time_starttransfer:从开始到服务器准备返回第一个字节时的耗时
    • time_total:整个 HTTP 请求操作耗时

输出结果如下:

time_namelookup: 0.002275
time_connect: 0.013750
time_appconnect: 0.039952
time_redirect: 0.000000
time_pretransfer: 0.040041
time_starttransfer: 0.051713
time_total: 0.135286

通过上述输出,我们可以计算出各个步骤的时间,例如:

  • DNS 解析:2ms
  • TCP 连接:time_connect(13ms) - time_namelookup(2ms) = 11ms
  • 服务器处理:time_starttransfer(51ms) - time_pretransfer(40ms) = 11ms
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值