理解和测量HTTP时序帮助我们去发现客户端与服务器、服务器与服务器之间通信的性能瓶颈。本文阐述了在一次HTTP请求中的时序,并展示了如何在Node.js中进行测量。
在我们谈及到HTTP时序之前,让我们看一下基本的概念:
时间段的解释:
举个例子:如果你的DNS查询比你期望的时间更长,这个问题可能是因为你的DNS供应商或者DNS缓存引起的。
当时间比Time to First Byte更长时,应该检查端点之间的延迟,还有当前服务器的负载。
Content Transfer过慢可能是由于返回的数据太大不够高效(无用的JSON属性值等)或者过慢的网络连接等。
使用Node.js测量HTTP的时序,我们需要订阅一个特定的HTTP请求、响应和socket事件。这里有一个只关注时序的简短Node.js代码片段。
const timings = {
// use process.hrtime() as it's not a subject of clock drift
startAt: process.hrtime(),
dnsLookupAt: undefined,
tcpConnectionAt: undefined,
tlsHandshakeAt: undefined,
firstByteAt: undefined,
endAt: undefined
}
const req = http.request({ ... }, (res) => {
res.once('readable', () => {
timings.firstByteAt = process.hrtime()
})
res.on('data', (chunk) => { responseBody += chunk })
res.on('end', () => {
timings.endAt = process.hrtime()
})
})
req.on('socket', (socket) => {
socket.on('lookup', () => {
timings.dnsLookupAt = process.hrtime()
})
socket.on('connect', () => {
timings.tcpConnectionAt = process.hrtime()
})
socket.on('secureConnect', () => {
timings.tlsHandshakeAt = process.hrtime()
})
})
DNS Lookup(DNS查询) 只在有域名的情况才有。
// There is no DNS lookup with IP address
const dnsLookup = dnsLookupAt !== undefined ?
getDuration(startAt, dnsLookupAt) : undefined
TCP Connectio(TCP连接)当host的问题解决后会立刻建立连接:
const tcpConnection = getDuration((dnsLookupAt || startAt), tcpConnectionAt)
TLS handshake (SSL) 只发生在HTTPS的请求协议中:
// There is no TLS handshake without https
const tlsHandshake = tlsHandshakeAt !== undefined ?
getDuration(tcpConnectionAt, tlsHandshakeAt) : undefined
我们等待服务器去发送 First Byte(第一个字节):
const firstByte = getDuration((tlsHandshakeAt || tcpConnectionAt), firstByteAt)
Content Transfer(内容传送) 开始于第一个字节流:
const contentTransfer = getDuration(firstByteAt, endAt)
Total Duration(总共持续时长) 由开始到最后的计算:
const total = getDuration(startAt, endAt)
在GitHub上完整的例子:example
现在我们已经知道了Node去测量HTTP时序,让我们看一下现有的工具去帮助你理解HTTP请求。
request
模块流行的request模块具有内置的HTTP时序测量方法。您可以使用time
属性启用它。
const request = require('request')
request({
uri: 'https://risingstack.com',
method: 'GET',
time: true
}, (err, resp) => {
console.log(err || resp.timings)
})
可以使用分布式跟踪工具收集HTTP时序,并在时间轴上可视化它们。这样,您可以全面了解后台发生的情况,以及构建分布式系统的实际成本是多少。
RisingStack的opentracing-auto库具有内置的标志,可以通过OpenTracing收集所有的HTTP时序。
Jaeger使用opentracing-auto测量HTTP请求。
使用Node.js测量HTTP的时序可以帮助发现性能瓶颈。Node的生态系统提供了大量的好的工具去从你的应用中提取这些应用指标。
往期精选文章 |
---|
使用虚拟dom和JavaScript构建完全响应式的UI框架 |
扩展 Vue 组件 |
使用Three.js制作酷炫无比的无穷隧道特效 |
一个治愈JavaScript疲劳的学习计划 |
全栈工程师技能大全 |
WEB前端性能优化常见方法 |
一小时内搭建一个全栈Web应用框架 |
干货:CSS 专业技巧 |
四步实现React页面过渡动画效果 |
让你分分钟理解 JavaScript 闭包 |
小手一抖,资料全有。长按二维码关注京程一灯,阅读更多技术文章和业界动态。