如果拿到一个nodejs服务系统的指标,如何判断这个这个服务有问题?
USE 方法
- Utilization(利用率):资源在时间段内被使用的百分比
- Saturation(饱和度):资源排队等待的数量
- Errors(错误数):运行过程中出现的错误数量
什么资源定义呢?
应用依赖的硬件或环境资源,如CPU、硬盘、内存等。
利用率:以CPU为例,90%利用率表示该CPU在该时间段内90%时间处于工作状态,这就是CPU的利用率(Utilization)。
饱和度:如果某个资源有5个用户等待,当前饱和度即为5。
错误数:在运行过程中出现了错误数。比如,网络接口有50次超时。
判别或观察一个系统需要从三个方面入手:利用率、饱和度、误差或错误数。
基于这一思路,我们需要使用use method进行观察或问题定位。
Node.js的 use 方法需要观察的核心指标包括:CPU、内存和吞吐量这三类。
CPU
计算密集型
计算和逻辑判断量非常大且集中的任务类型。
特点:
- 主要占用CPU资源,又称CPU密集型;
- 当任务数等于CPU核心数时,CPU运行效率最高,也就是CPU跑满了;
关键认知:计算密集型任务会显著占用CPU资源。
IO密集型
磁盘读取和输出数据量非常大的任务类型。
特点:
- IO操作时间远大于CPU和内存运行时间;
- 任务大部分时间在等待IO操作完成;
- CPU消耗相对较小但并非完全空闲;
系统瓶颈:主要出现在硬盘性能上。
常见误解:90%利用率可能被误认为CPU 90%时间都在执行计算。
实际情况:CPU可能处于多种状态
- Busy:真正执行计算任务
- Waiting(stalled):等待内存访问(主要是读内存)
- Waiting(idle):完全空闲
停顿状态:CPU在等待内存返回时不能执行指令,应用代码也会暂停 性能瓶颈:由于CPU发展远快于内存,大部分时间CPU在等待内存返回 重要结论:高CPU利用率不一定由计算密集型任务导致,过多的内存操作同样可能造成。
排查计算密集型CPU的利器:火焰图。
火焰图(Flame Graph)是专精于运维领域的性能分析工具。
坐标含义:
- X轴:表示CPU运行时间长度
- Y轴:从上到下表示从应用层到底层系统
分析要点:
- 条幅宽度表示占用CPU时间的多少
- 宽条幅表示该逻辑占用大量CPU时间
- 可逐层分析具体消耗CPU时间的代码逻辑
下面演示下如何用 0x 这个npm包来测试CPU。
新建app.js
"use strict";
import express from "express";
const server = express();
function a() {
for (let i = 0; i < 1e8; i++) {}
}
function b() {
for (let i = 0; i < 2e8; i++) {}
}
server.get("/", (req, res, next) => {
a();
b();
res.send("hello world");
});
server.listen(3000, () => {
console.log("listen at: http://127.0.0.1:3000/");
});
process.on("SIGINT", function () {
console.error("Caught SIGINT, shutting down.");
server.close();
});
安装依赖:
pnpm add 0x autocannon -D
脚本命令:
"scripts": {
"test": "NODE_ENV=production 0x -P 'autocannon http://localhost:3000/' ./app.js"
},
用 0x 工具来启动 app.js,然后用压测工具 utocannon 来进行压测,默认并发 10 连接,持续 10 秒。
执行后会生成一个文件:
用浏览器打开html文件,就可以看到 a函数 和 b函数分别利用CPU的时长了,刚好b函数差不多是a函数的两倍。
通过 ox 火焰图就能分析一段代码运行CPU的时长了。