nodejs 性能监控,

  nodejs 性能监控,

  如何获取节点性能监控指标?本文就和大家聊聊节点性能监控指标的获取方法,希望对你有所帮助!

  node.js速度课程简介:进入学习

  最近学习了nodejs监控的知识。虽然我没有精力去学习写一个简单版的监控,但是我还是忍不住知道了这些指标是怎么得到的(查阅了很多资料,觉得国内网上关于这个内容的介绍太少了,自己也在整理服务器节点的知识点,所以总结了这篇文章,分享给大家)。

  这篇文章有些指标可能有问题。欢迎交流。其实你可以把这些数据整理出来,写入一个监控数据库,供自己的中小型项目使用。然后前端react有bizcharts,g2等工具,前端自己画数据屏。我觉得esay monitor收集的数据维度没有我们的完整。

  服务器的性能瓶颈通常如下:

  CPU利用率CPU负载(内存磁盘I/O吞吐量)每秒查询率QPS(每秒查询数)日志监控/真实QPS响应时间进程监控

获取 CPU 指标

   CPU利用率和CPU负载,两者都可以在一定程度上反映一台机器的繁忙程度。

  

CPU 使用率

   CPU利用率是正在运行的程序所占用的CPU资源,表示机器在某个时间点正在运行的程序。使用率越高,说明这个时候机器运行的程序很多,反之亦然。利用率直接关系到CPU的强弱。让我们看看相关的API和一些名词解释,帮助我们理解获取CPU利用率的代码。

  

os.cpus()

  返回包含每个逻辑CPU核心信息的对象数组。

  model:指定CPU内核型号的字符串。

  speed:指定CPU内核速度的数字(单位为MHz)。

  times:具有以下属性的对象:

  用户CPU在用户模式下花费的毫秒数。nice CPU在良好模式下花费的毫秒数。CPU处于系统模式的毫秒数。空闲CPU在空闲模式下花费的毫秒数。irq CPU在中断请求模式下花费的毫秒数。注意:这个值只适用于POSIX。在Windows操作系统上,所有nice处理器的值总是0。

  当你看到用户,nice field,有些同学被它的优点淹没了,我也是,所以我仔细查了一下它的意思,请继续。

  

user

  用户表示CPU从010到59000运行的时间百分比。

  应用进程执行分为用户态用户态:CPU在用户态执行应用进程本身的代码逻辑,通常是一些内核态或者逻辑;CPU在内核状态下执行由进程发起的系统调用,通常是为了响应进程对资源的请求。

  用户程序是不属于内核的任何进程。Shell、编译器、数据库、Web服务器和桌面相关程序都是用户空间进程。如果处理器没有空闲,大部分CPU时间用于运行用户空间进程是正常的。

  

nice

   nice表示CPU运行在数值计算的百分比,低优先级表示进程nice值小于0。

  

system

  用户表示CPU从010到59000运行的时间百分比。

  一般来说,低优先级用户态的CPU利用率应该不会太高,除非应用进程发起大量的系统调用。过高则意味着系统调用时间长,比如频繁的IO操作。

  

idle

   idle表示CPU处于空闲状态的时间比例,在空闲状态下CPU没有任务要执行。

  

irq

   irq表示CPU处理内核态的时间比例。

  内核态就是一个典型的例子:网卡收到数据包后,通过硬件中断通知CPU进行处理。如果系统的网络流量很大,可以明显提高irq的利用率。

  

结论:

  用户状态小于70%,内核状态小于35%,整体状态小于70%,可以算作健康状态。

  以下示例说明了os.cpus()方法在Node.js中的用法:

  硬件中断

  //Node.js程序来演示

  //OS . CPU()方法

  //分配操作系统模块

  const OS=require( OS );

  //打印os.cpus()值

  console . log(OS . CPU());网卡中断

  [ {型号:英特尔酷睿i5-7200U CPU @ 2.50GHz ,

  速度:2712,

  次数:

  {用户:900000,nice:0,sys:940265,idle:11928546,irq:147046 } },

  {型号:英特尔酷睿i5-7200U CPU @ 2.50GHz ,

  速度:2712,

  次数:

  {用户:860875,nice:0,sys:507093,idle:12400500,irq:27062 } },

  {型号:英特尔酷睿i5-7200U CPU @ 2.50GHz ,

  速度:2712,

  次数:

  {用户:1273421,nice:0,sys:618765,idle:11876281,irq:13125 } },

  {型号:英特尔酷睿i5-7200U CPU @ 2.50GHz ,

  速度:2712,

  次数:

  {user: 943921,nice: 0,sys: 460109,idle: 12364453,IRQ: 12437}}]下面是如何获取cpu利用率的代码。

  const OS=require( OS );

  const sleep=ms=new Promise(resolve=setTimeout(resolve,ms));

  OSUtils类

  构造函数(){

  this.cpuUsageMSDefault=1000//CPU利用率默认时间段

  }

  /**

  *获取某段时间内的CPU利用率

  * @ param { Number } options . ms[时间段,默认为1000ms,即1秒]

  * @ param { boolean } options . percentage[true(以百分比结果形式返回)false]

  * @returns { Promise }

  */

  async getCPUUsage(options={}) {

  const that=this

  设{ cpuUsageMS,percentage }=options

  cpuUsageMS=cpuUsageMS that . cpuusagemsdefault;

  常数t1=that。_ getcpuiinfo();//t1时间点的CPU信息

  等待睡眠(cpuUsageMS);

  常数t2=that。_ getcpuiinfo();//T2时间点的CPU信息

  const idle=T2 . idle-t1 . idle;

  常数总计=T2 . total-t1 . total;

  设使用量=1 -空闲/总;

  if(百分比)使用量=(使用量* 100.0)。to fixed(2)“%”;

  返回用法;

  }

  /**

  *获取CPU瞬时时间信息

  * @返回{Object} CPU信息

  *用户数CPU在用户模式下花费的毫秒数。

  * nice number CPU在良好模式下花费的毫秒数。

  sysnumber CPU处于系统模式的毫秒数。

  * Idle Number CPU处于空闲模式的毫秒数。

  * IRQ number CPU在中断请求模式下花费的毫秒数。

  */

  _ getcpuiinfo(){

  const CPU=OS . CPU();

  设user=0,nice=0,sys=0,idle=0,irq=0,total=0;

  for(让cpu在CPU中){

  const times=CPU[CPU]。时代;

  user=times.user

  nice=times.nice

  sys=times.sys

  idle=times.idle

  irq=times.irq

  }

  total=用户友好系统空闲irq

  返回{

  用户,

  sys,

  闲着,

  总计,

  }

  }

  }

  const cpuUsage=new OSUtils()。getCPUUsage({ percentage:true });

  console.log(cpuUsage:,CPU usage . then(data=console . log(data)));//我的电脑是6.15%

CPU 负载

   CPU负载(loadavg),这个很好理解。意思是一定时间内,进程占用CPU时间和等待CPU时间的数量就是平均负载(load average)。这里等待CPU时间的进程指的是等待被唤醒的进程,不包括处于等待状态的进程。

  在此之前,我们需要学习一个节点API。

  

os.loadavg()

  返回包含1、5和15分钟平均负载的数组。

  平均负载是由操作系统计算的系统活动的量度,用小数表示。

  平均负载是Unix特有的概念。在Windows上,返回值总是[0,0,0]。

  用来描述操作系统当前的繁忙程度,可以简单理解为单位时间内CPU正在使用和等待使用的任务的平均数量。CPU负载过高,说明进程太多,可能体现在用Node中的故宫模块反复启动新的进程。

  const OS=require( OS );

  CPU线程的数量

  const length=os.cpus()。长度;

  //单核CPU平均负载,返回包含1、5、15分钟平均负载的数组。

  os.loadavg()。map(荷载=荷载/长度);

内存指标

  我们先解释一个API,不然你看不懂我们获取内存指标的代码。

  

process.memoryUsage():

  该函数返回四个参数,其含义和区别如下:

  Rss:(常驻集大小)操作系统分配给进程的总内存大小。包括所有C和JavaScript对象和代码。(例如,堆栈和代码片段)heapTotal:堆的总大小,包括3个部分,分配的内存,用于创建和存储对象。它对应于未分配但可用于分配的未分配内存。例如,垃圾收集(GC) heapUsed之前对象之间的内存碎片:分配的内存,即堆中所有对象的总大小,是heapTotal的子集。External:进程使用的系统链接库占用的内存,比如buffer,就是属于external的数据。缓冲区数据不同于其他对象。它不经过V8的内存分配机制,所以没有堆内存大小限制。使用下面的代码打印一个子进程的内存使用情况,可以看到rss大致等于top命令的RES。另外,主进程的内存只比子进程小33M,所以它们的内存占用是独立统计的。

  var showMem=function(){

  var mem=process . memoryusage();

  var format=函数(字节){

  返回(字节/1024/1024)。to fixed(2)“MB”;

  };

  console.log(Process: heapTotal 格式(mem.heapTotal) heapUsed 格式(mem.heapUsed) rss 格式(mem.rss)外部:格式(mem . external));

  console . log(-);

  };对于Node来说,一旦发生内存泄漏,就不那么容易排除故障了。如果监测到内存只升不降,那么一定是内存泄漏问题。健康的内存使用应该上下波动。当访问量大时,它上升,而访问量下降。

  

获取内存指标的代码

   const OS=require( OS );

  //检查当前节点进程的内存使用情况

  const { rss,heapUsed,heap total }=process . memoryusage();

  //获取系统的空闲内存

  const system free=OS . free mem();

  //获取系统的总内存

  const system total=OS . total mem();

  模块.导出={

  内存:()={

  返回{

  系统:1-系统空闲/系统总,//系统内存占用率

  Heap: heapUsed/headTotal,//当前节点进程内存占用率

  Node: rss/systemTotal,//当前节点进程内存与系统内存的比值

  }

  }

  }

磁盘空间指标

  磁盘监控主要监控磁盘使用情况。由于频繁写日志,磁盘空间逐渐用完。一旦磁盘不够用,就会造成系统的各种问题。设置磁盘使用的上限。一旦磁盘使用率超过警告值,服务器管理员应该整理日志或清理磁盘。

  以下代码引用了easy monitor3.0

  首先,使用df -P获取所有磁盘状况。这个-P用于防止换行符startsWith(/)成为真实的磁盘,而不是虚拟的行。*$)/)=匹配磁盘条件和装载的磁盘,如“1%/system/volumes/preboot”。Match[2]表示装入的磁盘名称const { exec sync }=require( child _ process );

  const result=execSync(df -P ,{ encoding: utf8})

  const lines=result . split( \ n );

  常量度量={ };

  lines.forEach(line={

  if(line . starts with(/){

  const match=line . match(/(\ d)% \ s(\/)。*$)/);

  如果(匹配){

  const rate=parse int(match[1] 0);

  const mounted=match[2];

  如果(!mounted.startsWith(/Volumes/)!mounted . starts with(/private/){

  公制[挂载]=速率;

  }

  }

  }

  });

  console . log(metric)

I/O指标

   I/O负载主要指磁盘I/O,反应的是磁盘上的读写情况。对于Node写的应用,主要是为了网络服务,不太可能I/O负载过高。多看书的I/O压力来自于数据库。

  要获得I/O指示器,我们需要知道一个名为iostat的linux命令。如果没有安装,则需要安装。让我们看看为什么这个命令可以反映I/O指示器。

  iostat -dx

  属性描述

  Rrm/s:每秒merge的读取操作数。即rmerge/s(每秒钟对这个设备的读请求合并的次数,文件系统会合并读同一块的请求)。

  Wrqm/s:每秒merge的写操作数。即wmerge/s(每秒合并对此设备的写请求的次数)。

  R/s:每秒读取I/O设备的数量。里约/南方

  W/s:每秒完成的I/O设备写入次数。Wio/s

  Rsec/s:每秒读取的扇区数量。Rsect/s

  Wsec/s:每秒的写入扇区数。Wsect/s

  RkB/s:每秒读取的K字节数。因为每个扇区的大小是512字节。

  WkB/s:每秒写入的K字节数。半秒钟.

  Avgrq-sz:每个设备I/O操作的平均数据大小(扇区)。

  Avgqu-sz:平均输入输出队列长度。

  Await:每个设备I/O操作的平均等待时间(毫秒)。

  Svctm:每个设备I/O操作的平均处理时间(ms)。

  %util:一秒中有多少百分比是用于I/O操作的,也就是io消耗cpu的百分比?我们只能监视%util。

  如果范例1:,I/O请求太多,如果输出:,磁盘可能有瓶颈。

  如果await远大于svctm,说明I/O队列太长,应用程序的响应时间慢。如果响应时间超过了用户允许的范围,那么可以考虑更换更快的磁盘,调整内核电梯算法,优化应用程序,或者升级CPU。

  

响应时间RT监控

  监控Nodejs的页面响应时间。该方案选自廖雪峰先生的博客文章。

  最近想监控Nodejs的表现。记录日志太麻烦了。最简单的方法是记录每个HTTP请求的处理时间,直接在HTTP响应头中返回。

  记录HTTP请求的时间很简单,就是接收请求时记录一个时间戳,响应请求时记录另一个时间戳。两个时间戳之间的差异是处理时间。

  但是,res.send()代码遍布js文件,所以我们不能更改每个URL处理函数。

  正确的思路是用中间件来实现。但是Nodejs没有任何方法来拦截res.send()。怎么破?

  其实只要我们稍微转变一下思路,放弃传统的OOP方式,把res.send()当成一个函数对象,就可以先保存原来的处理函数res.send,然后用自己的处理函数替换res.send:

  app.use(function (req,res,next) {

  //记录开始时间:

  var exec _ start _ at=date . now();

  //保存原始处理函数:

  var _ send=res.send

  //绑定我们自己的处理函数:

  res.send=function () {

  //发送标头:

  res.set(X-Execution-Time ,String(date . now()-exec _ start _ at));

  //调用原始处理函数:

  return _send.apply(res,arguments);

  };

  next();

  });完成时间戳只需要几行代码。

  不需要处理res.render()方法,因为res.send()是由res.render()内部调用的。

  当调用apply()函数时,传入res对象非常重要,否则原始处理函数的this指向undefined,直接导致错误。

  主页的实测响应时间为9毫秒。

  

监控吞吐量/每秒查询率 QPS

  名词解释:

  

一、QPS,每秒查询

   QPS: Queries per second的意思是“query rate per second”,即一台服务器每秒钟可以响应的查询数量,是衡量特定查询服务器在指定时间内处理多少流量的指标。

  在互联网中,一台机器作为DNS服务器的性能通常以每秒的查询速率来衡量。

  

二、TPS,每秒事务

   TPS:是TransactionsPerSecond的缩写,即每秒的事务数。它是软件测试结果的度量单位。事务是客户端向服务器发送请求,然后服务器做出反应的过程。客户端在发送请求时开始计时,在收到服务器的响应后结束计时,从而计算出所用的时间和完成的事务数。

  QPS vs TPS:QPS基本上和TPS差不多,不同的是对于一个页面的一次访问,形成一个TPS;但是,一个页面请求可能会生成对服务器的多个请求,服务器可以将这些请求计入QPS。比如访问一个页面会请求服务器两次,一次访问会产生一个“T”和两个“Q”。

  

三、RT,响应时间

  响应时间:从请求开始到接收响应数据结束所花费的总时间,即从客户端发起请求到从服务器收到响应结果的时间。

  响应时间RT(Response-time)是一个系统最重要的指标之一,它的值直接反映了系统的速度。

  

四、并发数

  并发是指系统可以同时处理的请求数量,也反映了系统的负载能力。

  

五、吞吐量

  系统的吞吐量(承压能力)与请求、外部接口、IO等CPU消耗密切相关。单个请求的CPU消耗越高,外部系统的接口和IO速度越慢,系统的吞吐量越低,反之亦然。

  系统吞吐量的几个重要参数:QPS(TPS)、并发和响应时间。

  QPS (TPS):(每秒查询数)每秒请求//事务数

  并发性:系统同时处理的请求//事务的数量。

  响应时间:一般取平均响应时间。

  理解了以上三个要素的含义后,我们就可以计算它们之间的关系了:

  %util 接近 100%I/O系统已经满负荷:

六、实际举例

  我们通过一个例子把上面的概念串起来。根据二八定律,如果80%的日访问量集中在20%的时间内,这20%的时间称为高峰时间。

  公式:(总PV * 80%)/(每天秒数* 20%)=高峰时间每秒的请求数(QPS)机器数:高峰时间每秒的QPS数/单台机器的QPS=QPS(TPS)= 并发数/平均响应时间所需机器数

  (3000000 * 0.8)/(86400 * 0.2)=139(QPS)

  并发数 = QPS*平均响应时间

  139/58=3

  在这里,以后做一般中小型项目的前端架构,部署自己的节点服务,就知道需要多少台机器组成一个集群才能报ppt了。哈哈,可以用pv算一个初值。

  我们需要了解压力测试(我们需要通过压力测试获得qps)。以ab命令为例:

  命令格式:

  AB [options] [http://]主机名[:端口]/路径的常用参数如下:

  -n请求请求总数

  -c并发并发数

  -t time limit测试所用的最大秒数,可用作请求的超时时间。

  -p postfile是包含需要发布的数据的文件。

  -测试post数据使用的内容类型头信息的内容类型复制代码,例如测试GET请求接口:

  a b-n 10000-c 100-t 10 http://127 . 0 . 0 . 1:8080/API/v1/posts?Size=10 获取以下数据:

  我们从中获得了几个关键指标:

  吞吐率(每秒请求数)有一个定量描述,它在图上显示了服务器的并发处理能力。单位是reqs/s,是指单位时间内一定数量的并发用户处理的请求数。在一定的并发用户数下,单位时间内可以处理的最大请求数称为最大吞吐率。

  记住:吞吐率是基于并发用户的数量。这句话代表了两层意思:

  A.吞吐率与并发用户数量有关。b .在不同的并发用户下,吞吐率一般用不同的公式计算:

  请求总数/完成这些请求所用的时间。必须注意,该值代表当前机器的整体性能。数值越大越好。

  2、QPS每秒查询速率(Query Per Second)

  每秒查询速率QPS是特定查询服务器在指定时间内处理的流量的度量。在互联网上,一台机器作为DNS服务器的性能往往是以每秒查询率来衡量的,也就是每秒响应请求的数量,也就是最大吞吐量。

  计算公式

  QPS(TPS)=并发数/平均响应时间(每个请求的时间)上图中有每个请求的时间值,然后我们还有并发数据的数量,就可以计算QPS了。

  这个qps是压力测量数据,真实的QPS,可以通过测井监测获得。

  

日志监控

  正常情况下,随着系统的运行,我们的后台服务会生成各种日志,应用会生成访问日志、错误日志、运行日志、网络日志。我们需要一个展示平台来展示这些日志。

  一般来说,后端是用例如ELk来显示的。我们都是前端的ui老手,可以自己画定制的UI界面。我不想多说什么。主要原因是日志本身要打印出来符合一定的规范,这样格式化的数据更有利于分析和显示。

  而业务逻辑监控主要体现在日志中。通过监视异常日志文件的变化,根据异常的类型和数量来反映新的异常。有些异常与特定的子系统有关,监视异常也可以反映子系统的状态。

  实际业务的QPS值也可以在系统监控中反映出来。观察QPS的表现可以及时检查业务分工。

  此外,可以从访问日志中监控PV和UV。并能分析用户习惯,预测访问高峰。

  

响应时间

  这也可以通过访问日志来获得,并且需要在控制器上记录实际响应时间。

  

进程监控

  监控进程通常检查操作系统中运行的应用程序进程的数量。例如,对于多进程架构的节点应用,需要检查工作进程的数量。如果低于预期值,将发出警报。

  在linux下查看进程的数量很简单,

  如果我们通过Node提供child_process模块来实现多核CPU的利用。Child_process.fork()函数实现流程的复制。

  worker.js代码如下:

  var http=require(http)\

  http.createServer(function(req,res) {\

  res.writeHead(200,{ Content-Type : text/plain })\

  res.end(Hello World\n)\

  }).listen(math . round((1 math . random())* 1000), 127.0.0.1) \通过node worker.js启动它,它会监听1000到2000之间的随机端口。

  Master.js代码如下:

  var fork=require(child_process )。叉

  var CPU=require( OS )。CPU()

  for(var I=0;i cpus.lengthi ) {

  叉(。/worker . js’)

  }查看进程数量的命令如下:

  PS aux grep worker . js $ PS aux grep worker . js

  李珍1475 0.0 0.0 2432768 600 s003 S 3:27AM 0:00.00 grep worker . js \

  李真1440 0.0 0.2 3022452 12680 s003 S 3:25AM 0:00.14/usr/local/bin/node。/worker.js\

  李真1439 0.0 0.2 3023476 12716 s003 S 3:25AM 0:00.14/usr/local/bin/node。/worker.js\

  李真1438 0.0 0.2 3022452 12704 s003 S 3:25AM 0:00.14/usr/local/bin/node。/worker.js\

  Liz 1437 0.0 0.2 3031668 12696 s003s 3:25AM 0:00.15/usr/local/bin/node。/worker.js \关于node的更多信息,请访问:nodejs教程!节点性能监控指标就是这么得来的。获取方法分享的详细内容,更多请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: