怎么获取Node性能监控指标?获取方法分享( 二 )

CPU 负载CPU的负载(loadavg)很好理解 , 指某段时间内占用 CPU 时间的进程和等待 CPU 时间的进程数为平均负载(load average) , 这里等待CPU 时间的进程是指等待被唤醒的进程 , 不包括处于wait状态进程 。
在此之前我们需要学习一个node的API
os.loadavg()返回包含 1、5 和 15 分钟平均负载的数组 。
平均负载是操作系统计算的系统活动量度 , 并表示为小数 。
平均负载是 Unix 特有的概念 。 在 Windows 上 , 返回值始终为 [0, 0, 0]
它用来描述操作系统当前的繁忙程度 , 可以简单地理解为CPU在单位时间内正在使用和等待使用CPU的平均任务数 。 CPU load过高 , 说明进程数量过多 , 在Node中可能体现在用紫禁城模块反复启动新的进程 。
const os = require('os');// CPU线程数const length = os.cpus().length;// 单核CPU的平均负载 , 返回一个包含 1、5、15 分钟平均负载的数组os.loadavg().map(load => load / length);内存指标我们先解释一个API , 要么你看不懂我们获取内存指标的代码
process.memoryUsage():该函数返回4个参数 , 含义及差别如下:

    rss: (Resident Set Size)操作系统分配给进程的总的内存大小 。 包括所有 C++ 和 JavaScript 对象和代码 。 (比如 , 堆栈和代码段)heapTotal:堆的总大小 , 包括3个部分 ,
      已分配的内存 , 用于对象的创建和存储 , 对应于heapUsed未分配的但可用于分配的内存未分配的但不能分配的内存 , 例如在垃圾收集(GC)之前对象之间的内存碎片
    heapUsed: 已分配的内存 , 即堆中所有对象的总大小 , 是heapTotal的子集 。 external: 进程使用到的系统链接库所占用的内存 , 比如buffer就是属于external里的数据 。 buffer数据不同于其他对象 , 它不经过V8的内存分配机制 , 所以也不会有堆内存大小限制 。
用如下代码 , 打印一个子进程的内存使用情况 , 可以看出rss大致等于top命令的RES 。 另外 , 主进程的内存只有33M比子进程的内存还小 , 可见它们的内存占用情况是独立统计的 。
var showMem = function(){ var mem = process.memoryUsage(); var format = function(bytes){ return (bytes / 1024 / 1024).toFixed(2) + ' MB'; }; console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss) + ' external:' + format(mem.external)); console.log('-----------------------------------------------------------');};对于Node而言 , 一旦出现内存泄漏 , 不是那么容易排查 。 如果监控到内存只升不降 , 那么铁定存在内存泄露问题 。 健康的内存使用应该有升有降 。 访问大的时候上升 , 访问回落下降
获取内存指标的代码const os = require('os');// 查看当前 Node 进程内存使用情况const { rss, heapUsed, heapTotal } = process.memoryUsage();// 获取系统空闲内存const systemFree = os.freemem();// 获取系统总内存const systemTotal = os.totalmem();module.exports = { memory: () => { return { system: 1 - systemFree / systemTotal, // 系统内存占用率 heap: heapUsed / headTotal, // 当前 Node 进程内存占用率 node: rss / systemTotal, // 当前 Node 进程内存占用系统内存的比例 } }}磁盘空间指标磁盘监控主要是监控磁盘的用量 。 由于日志频繁写的缘故 , 磁盘空间被渐渐用光 。 一旦磁盘不够用 , 将会引发系统的各种问题 。 给磁盘的使用量设置一个上限 , 一旦磁盘用量超过警戒值 , 服务器的管理者就应该整理日志或者清理磁盘 。
以下代码参考easy monitor3.0
    先用df -P获得所有磁盘情况 , 这个-P是为了防止有换行startsWith('/')保证是真实磁盘 , 不是虚拟的line.match(/(\d+)%\s+(/.*$)/) => 匹配磁盘情况和挂载的磁盘 , 比如'1% /System/Volumes/Preboot'match[1]是字符串 , 表示使用率 , match[2]表示挂载的磁盘名称
const { execSync } = require('child_process');const result = execSync('df -P', { encoding: 'utf8'})const lines = result.split('\n');const metric = {};lines.forEach(line => { if (line.startsWith('/')) { const match = line.match(/(\d+)%\s+(\/.*$)/); if (match) { const rate = parseInt(match[1] || 0); const mounted = match[2]; if (!mounted.startsWith('/Volumes/') && !mounted.startsWith('/private/')) { metric[mounted] = rate; } } }});console.log(metric)I/O指标I/O负载指的主要是磁盘I/O 。 反应的是磁盘上的读写情况 , 对于Node编写的应用 , 主要是面向网络服务 , 是不太可能出现I/O负载过高的情况 , 多读书的I/O的压力来源于数据库 。

推荐阅读