自定义指标
一、CPU 指标
1.1 CPU 负载
nodejs_cpu_load_average
CPU
负载情况。
CPU
负载 描述的是系统中等待 CPU
执行的任务数量。一般来说,它可以理解为系统队列中任务的数量,包括正在运行和等待运行的任务。CPU
负载的数值越高,说明系统任务越多,CPU
负载越重;数值越低,说明系统任务较少,CPU
有更多的闲暇时间。
CPU
负载 通常以平均值的形式显示,分为 1 分钟平均负载、5 分钟平均负载 和 15 分钟平均负载。这些数值分别表示系统在过去 1 分钟、5 分钟 和 15 分钟内 的平均负载。这个平均值可以帮助我们判断系统的负载趋势和波动情况。
CPU
负载 反映的是系统的整体负载情况,表示系统的繁忙程度,包括等待 CPU
和 I/O
资源的进程。负载不一定与 CPU
使用率直接相关。
const os = require('os');
const promClient = require('prom-client');
// 创建一个 Gauge 类型的指标,用于获取 CPU 负载平均值
const loadAvgGauge = new promClient.Gauge({
name: 'nodejs_cpu_load_average',
help: 'CPU load average for 1, 5, 15 minutes',
labelNames: ['time_window'],
collect() {
// 获取 CPU 的 1分钟、5分钟和15分钟负载平均值
const loadAvg = os.loadavg();
// 设置负载平均值到对应的标签
this.labels('1_min').set(loadAvg[0]);
this.labels('5_min').set(loadAvg[1]);
this.labels('15_min').set(loadAvg[2]);
}
});
我们可以通过 Node.js
中的 os.loadavg()
方法获取系统的负载平均值(即 1 分钟、5 分钟和 15 分钟的负载平均值)
1.2 CPU 使用率
nodejs_cpu_usage_percentage
CPU
使用率
CPU
使用率 是一个衡量计算机中央处理单元(CPU
)在给定时间内有多忙碌的指标。它表示在 CPU
能够使用的时间里,CPU
实际上被使用的时间百分比。简单来说,CPU
使用率反映了计算机的处理能力被消耗的程度。
-
0% CPU
使用率意味着CPU
完全空闲,没有任何任务在运行 -
100% CPU
使用率意味着CPU
在该时刻完全处于工作状态,没有闲置
CPU
使用率 主要关注的是 CPU
资源的实际使用情况,反映了 CPU
被占用的百分比。如果系统 CPU
使用率很高,通常意味着系统忙于处理任务。
const os = require('os');
const promClient = require('prom-client');
// 获取 CPU 使用率
function getCpuUsage() {
const cpus = os.cpus();
let totalIdle = 0;
let totalTick = 0;
cpus.forEach(cpu => {
const times = cpu.times;
totalIdle += times.idle;
totalTick += Object.values(times).reduce((acc, val) => acc + val, 0);
});
// 计算空闲时间和总时间的比例
const idle = totalIdle / cpus.length;
const total = totalTick / cpus.length;
const percentage = (1 - idle / total) * 100; // CPU 使用率
return percentage;
}
// 创建 Prometheus Gauge 指标
const cpuUsageGauge = new promClient.Gauge({
name: 'nodejs_cpu_usage_percentage',
help: 'CPU usage percentage',
collect() {
// 在 collect 中调用 getCpuUsage,并更新指标值
const percentage = getCpuUsage();
this.set(percentage); // 设置 Gauge 的值为计算出的 CPU 使用率
}
});
CPU
使用率 通常是通过以下方式计算的:
-
用户态(
User Time
):CPU
执行用户级程序的时间。 -
系统态(
System Time)
:CPU
执行内核操作的时间。 -
空闲态(
Idle Time
):CPU
没有执行任何任务的时间。 -
中断时间(
IRQ Time
):处理硬件中断的时间。
CPU
使用率 的计算公式一般是:
CPU 使用率 = (总时间 - 空闲时间) / 总时间 * 100
-
空闲时间:所有
CPU
核心的idle
时间的总和。 -
总时间:包括所有
CPU
核心的user
、system
和idle
时间的总和。
在 Node.js
中,我们可以使用 os.cpus()
获取每个 CPU
核心的时间数据,然后根据上述公式来计算 CPU
使用率。
二、请求指标
2.1 ART
nodejs_active_request_time_seconds (ART)
即活跃请求时间。在 Node.js
应用程序中,ART
指标用于表示处理某个请求的时间。具体而言,它衡量的是从接收到请求到处理完成的整个周期所消耗的时间,通常用秒或毫秒为单位。ART
可以帮助识别请求处理中的性能瓶颈。如果 ART
数值较高,说明请求的处理时间较长,可能是由于计算密集型操作、数据库查询、外部服务依赖等原因造成的。通过监控 ART
指标,可以在不同路由和方法级别上查看哪些请求花费的时间较长,从而进行优化,比如增加缓存、优化查询、减少阻塞操作等。
const { Gauge } = require("prom-client");
const artGauge = new Gauge({
name: "nodejs_active_request_time_seconds",
help: "The time spent processing a request in seconds",
labelNames: ["method", "path", "httpStatus", "code"],
});
async function artMiddleware(ctx, next) {
const start = process.hrtime();
await next();
const end = process.hrtime(start);
const durationInSeconds = end[0] + end[1] / 1e9;
const statusCode = ctx.status || 500;
artGauge
.labels(ctx.method, ctx.path, statusCode, `status_${statusCode}`)
.set(durationInSeconds);
}
router.get("/", artMiddleware, (ctx) => {
ctx.body = { code: 200, message: "成功!" };
});
2.2 TPS
TPS (Transactions Per Second)
是衡量系统或服务每秒处理多少事务的指标。它通常用于监控数据库、消息队列和应用层的事务处理能力。对于 Web
服务而言,TPS
代表的是每秒钟系统能够处理的业务请求或事务的数量。通过对 TPS
的监控,系统架构师可以更好地规划服务器的扩容和负载均衡,以适应日益增长的负载。如果 TPS
达到一定阈值并出现下降或不稳定,可以及时发现潜在的性能瓶颈或资源不足问题。
TPS
用来衡量系统处理每秒原子事务的能力,适用于那些涉及多个操作、需要事务保证的一致性的场景。TPS
则更侧重于事务处理,尤其是那些需要保证一致性和原子性的操作。例如: 在数据库中,一个事务可能包括插入、更新和删除等操作。QPS
用来衡量系统处理每秒请求的能力,通常适用于 无状态请求,且不需要事务处理的场景。QPS
是一个更宽泛的概念,适用于大多数的 HTTP
请求和查询操作,关注的是请求的频率。例如,一个 HTTP
请求可能只是查询或获取资源,并不涉及多步骤的操作。
// 每秒钟统计的请求数
let transactionCount = 0;
// 创建一个 Prometheus 指标 (TPS)
const tpsGauge = new promClient.Gauge({
name: 'nodejs_tps',
help: 'Transactions per second (TPS) for successful requests',
});
// 每秒钟的 TPS 计算
setInterval(() => {
// 当前秒的请求数即为 TPS
const tps = transactionCount;
console.log("TPS:", tps);
// 更新 Prometheus 指标
tpsGauge.set(tps);
// 重置计数器
transactionCount = 0;
}, 1000);
// 定义 TPS 计算中间件
async function tpsMiddleware(ctx, next) {
// 执行下一个中间件
await next();
// 只有成功的请求才会计入 TPS
if (ctx.status >= 200 && ctx.status < 300) {
transactionCount++; // 增加事务计数
}
}
// 使用 TPS 中间件
app.use(tpsMiddleware);
-
使用
setInterval
每秒钟获取当前的TPS
,并将其传递到Prometheus
的tpsGauge
指标中 -
由于
setInterval
依赖的计数器是每秒钟重置的,所以不需要在每个请求过程中更新Prometheus
指标(例如每个请求就更新一次),而是通过全局的setInterval
每秒一次更新,这样减少了频繁调用Prometheus API
。
2.3 真实 QPS
nodejs_real_qps
QPS (Queries per Second)
是衡量系统处理能力的一个重要指标,通常用于表示系统在每秒钟能够处理多少个请求。真实 QPS
是一种专注于计算真实、有效请求的 QPS
指标,区别于那些可能被错误请求、健康检查、静态资源请求等所影响的总 QPS
。也就是说,真实 QPS
更关注的是应用层实际处理的请求,通常用来反映应用的实际负载。真实 QPS
能够帮助评估实际业务请求的流量,帮助开发人员和运维团队进行容量规划。
真实 QPS
计算的是每秒处理的有效请求数,通常会排除掉错误请求、无效请求、超时请求等。更多地关注系统健康状况和正常请求的处理能力,排除掉可能对应用健康产生负面影响的请求。
TPS
用来衡量系统处理每秒原子事务的能力,适用于那些涉及多个操作、需要事务保证的一致性的场景。TPS
则更侧重于事务处理,尤其是那些需要保证一致性和原子性的操作。例如: 在数据库中,一个事务可能包括插入、更新和删除等操作。QPS
用来衡量系统处理每秒请求的能力,通常适用于 无状态请求,且不需要事务处理的场景。QPS
是一个更宽泛的概念,适用于大多数的 HTTP
请求和查询操作,关注的是请求的频率。例如,一个 HTTP
请求可能只是查询或获取资源,并不涉及多步骤的操作。
// 定义 Prometheus QPS 指标
const realQPSGauge = new promClient.Gauge({
name: 'nodejs_real_qps',
help: 'Real QPS for successful requests', // 描述指标
});
let requestCount = 0;
const QPS_RESET_INTERVAL = 1000;
async function realQPSMiddleware(ctx, next) {
try{
await next();
if (ctx.status >= 200 && ctx.status < 300) {
requestCount++;
}
}catch(error){
ctx.status = 500;
}
}
function updateQps() {
qpsGauge.set(requestCount);
requestCount = 0;
}
setInterval(updateQps, QPS_RESET_INTERVAL);
router.get("/", realQPSMiddleware, (ctx) => {
list.push(new Array(1000).fill("柏拉文"));
ctx.body = { code: 200, message: "成功!" };
});
通过使用 setInterval
来每隔一秒定期计算 QPS
,并且避免在每个请求中都进行计算,优化了性能和并发情况。同时,通过 labels
对请求进行区分,使得 Prometheus
指标可以更细粒度地展示请求的 QPS
。
-
使用
setInterval
每秒钟计算一次QPS
,并且清空计数器。这样做的好处是减少了每个请求的计算压力,不会频繁计算和更新QPS
。 -
每秒一次的定时计算使得
requestCount
可以作为局部计数器进行更新,避免了每个请求都进行QPS
计算的性能开销。 -
只有成功的请求(状态码在
200-299
之间)才会计入QPS
,对于错误请求会跳过计数。 -
每秒的
QPS
计算是单独进行的,并不会受到高并发影响,因为每个请求计数的操作是非阻塞的。我们将计数和计算逻辑分开,避免了由于高并发时的共享状态导致的竞态条件。
2.4 每秒 QPS
每秒 QPS(Queries Per Second)
nodejs_qps
是衡量系统每秒处理的请求数量的指标,通常用于衡量一个 Web
应用或服务的吞吐量。在 Node.js
中,QPS
代表每秒钟 HTTP
请求的数量。这个指标对于监控系统性能、分析应用负载、预测资源需求和调优服务器性能非常有用。了解高负载时的 QPS
,可以帮助我们提前进行容量规划,避免系统崩溃。可以根据设定的阈值,监控 QPS
指标来触发警报,及时发现系统故障或瓶颈。
每秒 QPS
:计算的是每秒处理的请求数,不区分请求类型和状态,所有请求都会计入。更多地用于吞吐量、系统负载的监控,帮助了解系统在特定时间段内的处理能。
TPS
用来衡量系统处理每秒原子事务的能力,适用于那些涉及多个操作、需要事务保证的一致性的场景。TPS
则更侧重于事务处理,尤其是那些需要保证一致性和原子性的操作。例如: 在数据库中,一个事务可能包括插入、更新和删除等操作。QPS
用来衡量系统处理每秒请求的能力,通常适用于 无状态请求,且不需要事务处理的场景。QPS
是一个更宽泛的概念,适用于大多数的 HTTP
请求和查询操作,关注的是请求的频率。例如,一个 HTTP
请求可能只是查询或获取资源,并不涉及多步骤的操作。
// 定义 Prometheus QPS 指标
const qpsGauge = new promClient.Gauge({
name: 'nodejs_qps',
help: 'Real QPS for successful requests', // 描述指标
});
let requestCount = 0;
const QPS_RESET_INTERVAL = 1000;
async function qpsMiddleware(ctx, next) {
try{
await next();
requestCount++;
}catch(error){
ctx.status = 500;
}
}
function updateQps() {
qpsGauge.set(requestCount);
requestCount = 0;
}
setInterval(updateQps, QPS_RESET_INTERVAL);
router.get("/", qpsMiddleware, (ctx) => {
list.push(new Array(1000).fill("柏拉文"));
ctx.body = { code: 200, message: "成功!" };
});
通过使用 setInterval
来每隔一秒定期计算 QPS
,并且避免在每个请求中都进行计算,优化了性能和并发情况。同时,通过 labels
对请求进行区分,使得 Prometheus
指标可以更细粒度地展示请求的 QPS
。
-
使用
setInterval
每秒钟计算一次QPS
,并且清空计数器。这样做的好处是减少了每个请求的计算压力,不会频繁计算和更新QPS
。 -
每秒一次的定时计算使得
requestCount
可以作为局部计数器进行更新,避免了每个请求都进行QPS
计算的性能开销。 -
每秒的
QPS
计算是单独进行的,并不会受到高并发影响,因为每个请求计数的操作是非阻塞的。我们将计数和计算逻辑分开,避免了由于高并发时的共享状态导致的竞态条件。