nodejs学习:如何发现nodejs应用的问题?

0 阅读3分钟

如果拿到一个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%时间都在执行计算。

image.png

实际情况:CPU可能处于多种状态

  • Busy:真正执行计算任务
  • Waiting(stalled):等待内存访问(主要是读内存)
  • Waiting(idle):完全空闲

停顿状态:CPU在等待内存返回时不能执行指令,应用代码也会暂停 性能瓶颈:由于CPU发展远快于内存,大部分时间CPU在等待内存返回 重要结论:高CPU利用率不一定由计算密集型任务导致,过多的内存操作同样可能造成。

排查计算密集型CPU的利器:火焰图

火焰图(Flame Graph)是专精于运维领域的性能分析工具。

image.png

坐标含义:

  • 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 秒。

执行后会生成一个文件:

image.png

用浏览器打开html文件,就可以看到 a函数 和 b函数分别利用CPU的时长了,刚好b函数差不多是a函数的两倍。

image.png

image.png

通过 ox 火焰图就能分析一段代码运行CPU的时长了。