提示:记录工作中遇到的需求及解决办法
文章目录
前言
最近一直在用 NestJs 开发一个企业级的商业化项目,对于要上线的项目,那必然就少不了性能监控了。了解这些指标对我们开发调优的时候至关重要。
服务器的性能瓶颈通常为以下几个:
- CPU 使用率
- CPU 负载(load)
- 内存
- 磁盘
- I/O
- 吞吐量 (Throughput)
- 每秒查询率 QPS(Query Per Second)
- 日志监控/真实 QPS
- 响应时间
- 进程监控
提示:以下是本篇文章正文内容,下面案例可供参考
CPU 使用率
CPU 使用率是一个衡量计算机中央处理单元(CPU)在给定时间内有多忙碌的指标。它表示在 CPU 能够使用的时间里,CPU 实际上被使用的时间百分比。简单来说,CPU 使用率反映了计算机的处理能力被消耗的程度。
- 100% CPU 使用率意味着 CPU 在该时刻完全处于工作状态,没有闲置。
- 0% CPU 使用率意味着 CPU 完全空闲,没有任何任务在运行。
CPU 使用率通常是通过以下方式计算的:
- 用户态(User Time):CPU 执行用户级程序的时间。
- 系统态(System Time):CPU 执行内核操作的时间。
- 空闲态(Idle Time):CPU 没有执行任何任务的时间。
- 中断时间(IRQ Time):处理硬件中断的时间。
CPU 使用率的计算公式一般是:
CPU 使用率 = (总时间 - 空闲时间) / 总时间 * 100%
其中,总时间是从上次采样以来的 CPU 总时间,空闲时间是从上次采样以来的 CPU 空闲时间。
Node.js 提供了 os 模块来获取操作系统的相关信息,包括 CPU 使用情况。虽然 os 模块本身没有直接提供获取 CPU 使用率的 API,但我们可以通过 os.cpus() 获取每个 CPU 核心的详细信息,并通过计算差值来获取 CPU 使用率。
os.cpus() 返回一个包含 CPU 核心信息的数组,每个元素代表一个 CPU 核心的信息,包含以下字段:
- model: CPU 型号
- speed: CPU 频率
- times: 各个时间段的时间信息,包括:
- user: 用户态时间
- nice: 用户态下的优先级调整时间
- sys: 系统态时间
- idle: 空闲时间
- irq: 中断时间
通过采样 CPU 的 times 数据,首先记录当前的 CPU 状态信息,然后等待一段时间后再次记录。在这两个时间点之间,计算每个核心的 idle 和 total 时间差,再根据差值推算出每个核心的 CPU 使用率。
如下代码所示:
const os = require("os");
// 获取 CPU 使用率的函数
function getCpuUsage() {
return new Promise((resolve, reject) => {
const startCpuInfo = os.cpus(); // 获取初始的 CPU 信息
setTimeout(() => {
const endCpuInfo = os.cpus(); // 获取采样后的 CPU 信息
// 计算各个核心的使用率
const cpuUsage = endCpuInfo.map((endCore, index) => {
const startCore = startCpuInfo[index];
// 计算起始和结束的时间差
const startTotal = Object.values(startCore.times).reduce(
(a, b) => a + b,
0
);
const endTotal = Object.values(endCore.times).reduce(
(a, b) => a + b,
0
);
const idleDiff = endCore.times.idle - startCore.times.idle;
const totalDiff = endTotal - startTotal;
const usage = (1 - idleDiff / totalDiff) * 100;
return {
core: index,
usage: usage.toFixed(2), // 保留两位小数
};
});
resolve(cpuUsage);
}, 100); // 延迟 100ms
});
}
// 调用获取 CPU 使用率的函数
getCpuUsage()
.then((cpuUsage) => {
console.log("CPU 使用率:");
cpuUsage.forEach((core) => {
console.log(`核心 ${
core.core} 使用率: ${
core.usage}%`);
});
})
.catch((err) => {
console.err