利用Node.js了解与测量HTTP所花费的时间详解


Posted in Javascript onSeptember 22, 2017

前言

了解和测量HTTP时间有助于我们发现客户端到服务器或服务器到服务器之间的通信性能瓶颈。 本文介绍了HTTP请求中的时间开销,并展示了如何在Node.js中进行测量。

在我们开始了解HTTP时间开销之前,让我们来看一些基本的概念:

  • IP(互联网协议):IP是网络层协议,涉及网络寻址和路由。 IP负责根据一个或多个IP网络上的数据包头将数据包从源主机传送到目标主机。 它还定义了封装要传递的数据的数据包结构。
  • DNS(域名服务器):DNS是一种分层分散式命名系统,用于将诸如risingstack.com的人类可读主机名解析为机器可读的IP地址。
  • TCP(传输控制协议):TCP标准定义了如何在应用程序之间建立和维护网络对话以交换数据。 TCP在通过IP网络通信的主机上运行的应用程序之间提供可靠,有序和错误检查的八位字节流。 HTTP客户端通过建立TCP连接来发起请求。
  • SSL / TLS(传输层安全性):TLS是一种通过计算机网络提供通信安全性的加密协议。 SSL(安全套接字层)是TLS的不推荐使用的前身。 TLS和SSL都使用证书建立安全连接。 SSL证书不依赖于加密协议(如TLS),证书包含密钥对:公钥和私钥。 这些密钥一起工作,建立一个加密的连接。

现在我们来看一下通常HTTP请求的时间表:

利用Node.js了解与测量HTTP所花费的时间详解

  • DNS查找:执行DNS查找所花费的时间。 DNS查找将域名解析为IP地址。 每个新的域需要一个完整的往返行程来进行DNS查找。 当目的地已经是IP地址时,没有DNS查找。
  • TCP连接:在源主机和目标主机之间建立TCP连接所需的时间。 必须在多步握手过程中正确建立连接。 TCP连接由操作系统管理,如果基础TCP连接无法建立,则OS范围的TCP连接超时将会进入我们应用程序中的超时配置。
  • TLS握手:完成TLS握手的时间。 在握手过程中,端点交换认证和密钥以建立或恢复安全会话。 没有HTTPS请求的不需要TLS握手。
  • 第一个字节的时间(TTFB):等待初始响应的时间。 此时间除了等待服务器处理请求和传递响应所花费的时间之外,还可以捕获往返服务器的延迟。
  • 内容传输:接收响应数据所花费的时间。 响应数据的大小和可用的网络带宽决定其持续时间。

如何通过HTTP时间开销帮助发现性能瓶颈?

例如,如果您的DNS查询所花费的时间比预期的要长,那么问题可能是您的DNS提供商或DNS缓存设置。

缓慢的内容传输可能是由效率低下的反应机构引起的,例如发回太多的数据(未使用的JSON属性等)或缓慢的连接。

测量Node.js中的HTTP时间开销

为了测量Node.js中的HTTP时间开销,我们需要订阅特定的请求,响应和套接字事件。 这是一个简短的代码片段,展示了如何在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查找只会发生在有域名的时候:

/ There is no DNS lookup with IP address
const dnsLookup = dnsLookupAt !== undefined ? 
 getDuration(startAt, dnsLookupAt) : undefined

TCP连接在主机解析后立即发生:

const tcpConnection = getDuration((dnsLookupAt || startAt), tcpConnectionAt)

TLS握手(SSL)只能使用https协议:

// There is no TLS handshake without https 
const tlsHandshake = tlsHandshakeAt !== undefined ? 
  getDuration(tcpConnectionAt, tlsHandshakeAt) : undefined

我们等待服务器开始发送第一个字节:

const firstByte = getDuration((tlsHandshakeAt || tcpConnectionAt), firstByteAt)

总持续时间从开始和结束日期计算:

const total = getDuration(startAt, endAt)

看到整个例子,看看我们的https://github.com/RisingStac...仓库。

测量时间的工具

现在我们知道如何使用Node测量HTTP时间,我们来讨论可用于了解HTTP请求的现有工具。

request module

著名的request module具有测量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时间。

利用Node.js了解与测量HTTP所花费的时间详解

在Jaeger中使用opentracing-auto的HTTP请求时序。

总结

使用Node.js测量HTTP时间可以帮助您发现性能瓶颈。 Node生态系统提供了很好的工具来从应用程序中提取这些指标。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

翻译自Understanding & Measuring HTTP Timings with Node.js

Javascript 相关文章推荐
非常不错的功能强大代码简单的管理菜单美化版
Jul 09 Javascript
漂亮的jquery提示效果(仿腾讯弹出层)
Feb 05 Javascript
onmouseover和onmouseout的一些问题思考
Aug 14 Javascript
js showModalDialog 弹出对话框的简单实例(子窗体)
Jan 07 Javascript
jquery实现页面加载效果
Feb 21 Javascript
JS简单获取当前日期时间的方法(如:2017-03-29 11:41:10 星期四)
Mar 29 Javascript
详解vue组件化开发-vuex状态管理库
Apr 10 Javascript
纯js实现动态时间显示
Sep 07 Javascript
vue数据双向绑定的注意点
Jun 23 Javascript
JS计算两个时间相差分钟数的方法示例
Jan 10 Javascript
如何在微信小程序里面退出小程序的方法
Apr 28 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
Jan 19 Javascript
原生JS实现日历组件的示例代码
Sep 22 #Javascript
BootstrapTable加载按钮功能实例代码详解
Sep 22 #Javascript
Bootstrap Table 删除和批量删除
Sep 22 #Javascript
jQury Ajax使用Token验证身份实例代码
Sep 22 #Javascript
Angular将填入表单的数据渲染到表格的方法
Sep 22 #Javascript
详解在express站点中使用ejs模板引擎
Sep 21 #Javascript
vue router学习之动态路由和嵌套路由详解
Sep 21 #Javascript
You might like
php常见的魔术方法详解
2014/12/25 PHP
PHP有序表查找之插值查找算法示例
2018/02/10 PHP
PHP实现微信提现功能
2018/09/30 PHP
php 中的信号处理操作实例详解
2020/03/04 PHP
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
2011/07/04 Javascript
简单时间提示DEMO从0开始一直进行计时
2013/11/19 Javascript
jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别
2013/12/02 Javascript
Node.js文件操作详解
2014/08/16 Javascript
JavaScript图片轮播代码分享
2015/07/31 Javascript
js+css实现文字散开重组动画特效代码分享
2015/08/21 Javascript
Jquery 自定义事件实现发布/订阅的简单实例
2016/06/12 Javascript
node.js报错:Cannot find module 'ejs'的解决办法
2016/12/14 Javascript
前端开发必知的15个jQuery小技巧
2017/01/22 Javascript
移动端利用H5实现压缩图片上传功能
2017/03/29 Javascript
AngularJs返回前一页面时刷新一次前面页面的方法
2018/10/09 Javascript
微信小程序实现的自定义分享功能示例
2019/02/12 Javascript
vue.js实现回到顶部动画效果
2019/07/31 Javascript
JS forEach跳出循环2种实现方法
2020/06/24 Javascript
微信小程序自定义modal弹窗组件的方法详解
2020/12/20 Javascript
python去掉行尾的换行符方法
2017/01/04 Python
python3大文件解压和基本操作
2017/12/15 Python
Python处理时间日期坐标轴过程详解
2019/06/25 Python
Django框架模板用法入门教程
2019/11/04 Python
django 外键创建注意事项说明
2020/05/20 Python
Python 程序员必须掌握的日志记录
2020/08/17 Python
python实现ping命令小程序
2020/12/28 Python
CSS3制作缩略图的详细过程
2016/07/08 HTML / CSS
Clearly澳大利亚:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
Python里面search()和match()的区别
2016/09/21 面试题
电子商务个人自荐信
2013/12/12 职场文书
网上开店必备创业计划书
2014/01/26 职场文书
文秘档案管理岗位职责
2014/03/06 职场文书
公司地址变更通知
2015/04/25 职场文书
企业管理不到位检讨书
2019/06/27 职场文书
Springboot如何同时装配两个相同类型数据库
2021/11/17 Java/Android
疑《守望先锋2》A测截图泄露 或将推出新模式、新界面
2022/04/03 其他游戏