利用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 相关文章推荐
javascript indexOf函数使用说明
Jul 03 Javascript
javascript查找字符串中出现最多的字符和次数的小例子
Oct 29 Javascript
JS去除字符串两端空格的简单实例
Dec 27 Javascript
EasyUI中实现form表单提交的示例分享
Mar 01 Javascript
WordPress中鼠标悬停显示和隐藏评论及引用按钮的实现
Jan 12 Javascript
React组件的三种写法总结
Jan 12 Javascript
写jQuery插件时的注意点
Feb 20 Javascript
基于vue的fullpage.js单页滚动插件
Mar 20 Javascript
JS失效 提示HTML1114: (UNICODE 字节顺序标记)的代码页 utf-8 覆盖(META 标记)的冲突的代码页 utf-8
Jun 23 Javascript
200行代码实现blockchain 区块链实例详解
Mar 14 Javascript
使用纯前端JavaScript实现Excel导入导出方法过程详解
Aug 07 Javascript
vue中this.$http.post()跨域和请求参数丢失的解决
Apr 08 Vue.js
原生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 Static关键字实用方法
2010/06/04 PHP
destoon实现资讯信息前面调用它所属分类的方法
2014/07/15 PHP
php图片添加水印例子
2016/07/20 PHP
PHP折半(二分)查找算法实例分析
2018/05/12 PHP
PHP+redis实现的悲观锁机制示例
2018/06/12 PHP
PHP配合fiddler抓包抓取微信指数小程序数据的实现方法分析
2020/01/02 PHP
JS Timing
2007/04/21 Javascript
Javascript 获取滚动条位置等信息的函数
2009/09/08 Javascript
Javascript 中介者模式实例
2009/12/16 Javascript
JS打印gridview实现原理及代码
2013/02/05 Javascript
Ajax同步与异步传输的示例代码
2013/11/21 Javascript
用js模拟struts2的多action调用示例
2014/05/19 Javascript
javascript数组克隆简单实现方法
2015/12/16 Javascript
JavaScript类型检测之typeof 和 instanceof 的缺陷与优化
2016/01/13 Javascript
node.js报错:Cannot find module 'ejs'的解决办法
2016/12/14 Javascript
原生js实现中奖信息无间隙滚动效果
2017/01/18 Javascript
vue-cli3 从搭建到优化的详细步骤
2019/01/20 Javascript
vue filter 完美时间日期格式的代码
2019/08/14 Javascript
使用vue实现HTML页面生成图片的方法
2020/03/12 Javascript
解决Vue 给mapState中定义的属性赋值报错的问题
2020/06/22 Javascript
python使用chardet判断字符串编码的方法
2015/03/13 Python
在Windows系统上搭建Nginx+Python+MySQL环境的教程
2015/12/25 Python
Python计时相关操作详解【time,datetime】
2017/05/26 Python
Python+tkinter使用80行代码实现一个计算器实例
2018/01/16 Python
Python根据字典的值查询出对应的键的方法
2020/09/30 Python
python自动化测试三部曲之request+django实现接口测试
2020/10/07 Python
HTML5离线缓存在tomcat下部署可实现图片flash等离线浏览
2012/12/13 HTML / CSS
html5使用canvas绘制文字特效
2014/12/15 HTML / CSS
Html5 new XMLHttpRequest()监听附件上传进度
2021/01/14 HTML / CSS
Ibood荷兰:互联网每日最佳在线优惠
2019/02/28 全球购物
开展党的群众路线教育实践活动方案
2014/02/05 职场文书
教师教学评估方案
2014/05/09 职场文书
委托公证书样本
2015/01/23 职场文书
舞蹈社团活动总结
2015/05/07 职场文书
最新农村养殖致富:资金投入较低的创业项目有哪些?
2019/09/26 职场文书
导游词之无锡丝业博物馆
2019/11/12 职场文书