All Articles

Node.JS Profile 3.1 CPU Usage

1. 前言

本文是系列文章Node.JS Profile的一部分,完整的文章列表请去总章查看。

本文主要负责介绍Node的CPU Profile相关工具及使用。

2. 目标

CPU相关监控的必要性应该也不需要在这里多说了,但当前这篇文章的目标并不是找出高CPU消耗的原因,这部分的技术和释疑放在了后面的4.1 Profile实践进行详述。

当前这篇文章的目标是让程序能够定时采集到CPU的用量,用来存入监控系统,以进行预警。

3. 工具选择

作为一个微型级别的功能,相关的工具库制作思路其实都非常简单,无非:

  • 根据node原生的os.cpus接口给出的数据进行计算
  • 根据node原生的process.cpuUsage([previousValue])接口给出的数据进行计算:该接口给出的仅只是当前进程CPU的耗时,而没有针对性的计算百分比,所以百分比的最终结果需要自己计算

前者能找到的有类似于jub3i/node-cpu-stat这样的工具,但按照os库里的API算出来的,都是机器CPU数据,而不是Node进程数据,故不太符合本文的目标。

后者才是符合当前需求的Node当前进程CPU占用消耗的数据,但实际上在找的时候,发现基本上这类的库都是前者,后者相当的少。偶尔有几个感觉计算也不是很对:

最后自制了一个:agreatfool/node-process-cpu-usage

如何使用:

const ProcessCPULoad = require('process-cpu-usage').ProcessCPULoad;

const tracker = new ProcessCPULoad();

tracker.start((total, user, system) => {
  console.log('CPU Usage: Total: %d, User: %d, System: %d', total, user, system);
});

测试1,制作一个WEB服务器入口:

#!/usr/bin/env node
"use strict";

const ProcessCPULoad = require("process-cpu-usage").ProcessCPULoad;

const tracker = new ProcessCPULoad("node"); // "node" | "linux"

tracker.start((total, user, system) => {
  console.log('CPU Usage: Total: %d, User: %d, System: %d', total, user, system);
}, 1000);

const express = require('express');
const app = express();

app.get('/test', (req, res) => {
  res.sendStatus(200);
});

app.listen(5000);
console.log('Server started, listening on port 5000 ...');

测试2,制作一个基于wrk发送请求的客户端脚本(lua脚本见:delay.lua):

#!/usr/bin/env bash

CONCURRENCY=55

wrk \
 -d 2h \
 -t ${CONCURRENCY} \
 -c ${CONCURRENCY} \
 -s ./bash/delay.lua \
 http://127.0.0.1:5000/test

先后启动后就可以在服务器脚本的控制台上看到CPU使用情况,此外可以使用linux系统的ps命令来查看对应进程的CPU使用情况来进行印证:

#!/usr/bin/env bash

PID=$(ps aux | grep "YOUR_SCRIPT_NAME.js" | grep -v "grep" | awk '{print $2}')

echo "Tracing cpu usage of pid: ${PID}"

while true; do
    sleep 1
    ps -p ${PID} -o %cpu | grep -v "%CPU"
done

4. Node工具和Linux原生工具的选择问题

Node原生的工具是使用Node的API来进行计算得到CPU使用的情况,该工具的最大问题就是当Node进程内部EventLoop阻塞的时候,监听的API就会无响应,对监控来说其实并不是一个最佳选择,类似运动员和裁判同台竞技。

所以有的时候可能选用Linux操作系统的ps命令来监控进程级别的CPU使用会更好。当然一切都看使用方的监控系统集成便利等因素,综合选用,没有所谓的最优解。

5. 资料

EOF

Published 2018/3/16

Some tech & personal blog posts