事件循环
一、nodejs_eventloop_lag_seconds
1.1 认识
nodejs_eventloop_lag_seconds
:这个指标记录了事件循环的延迟(lag
)时间,单位是秒。它是一个总览性的指标,反映了事件循环延迟的基本情况,帮助开发者快速了解事件循环的当前表现。
在 Node.js
中,事件循环延迟是一个重要的性能指标,它反映了 Node.js
事件循环处理异步任务的效率。我们可以通过两种方式来计算事件循环的延迟时间:一种是基于 process.hrtime()
,另一种是通过 Node.js
提供的 perf_hooks
模块中的 monitorEventLoopDelay API
。
1.1 process.hrtime 计算
process.hrtime()
提供了高精度的时间戳,可以帮助我们计算事件循环的延迟。通过计算事件循环开始和结束之间的时间差,我们可以获取事件循环的延迟时间。process.hrtime()
:适合用于需要高精度时间戳的手动计算场景。它提供了精确的纳秒级时间戳,但需要开发者手动计算延迟时间。
const http = require('http');
// 用于记录事件循环的延迟
let lastTimestamp = process.hrtime();
// 计算事件循环的延迟
function monitorEventLoopDelay() {
// 获取当前时间与上次时间的差值
const currentTimestamp = process.hrtime(lastTimestamp);
const elapsed = currentTimestamp[0] * 1000 + currentTimestamp[1] / 1e6; // 转换为毫秒
// 打印事件循环的延迟
console.log('Event Loop Delay (ms):', elapsed);
// 更新上次时间戳
lastTimestamp = process.hrtime();
}
// 每秒钟打印一次事件循环延迟
setInterval(monitorEventLoopDelay, 1000);
// 创建一个 HTTP 服务器(模拟应用的负载)
http.createServer((req, res) => {
res.end('Hello, Node.js Event Loop!');
}).listen(3000, () => {
console.log('Server is running at http://localhost:3000');
});
-
process.hrtime()
返回一个高精度时间戳,形式为[seconds, nanoseconds]
。 -
在每次
setInterval
调用时,我们使用process.hrtime(lastTimestamp)
来计算从上次计算到现在的时间差(单位为纳秒)。然后将其转换为毫秒。 -
这个延迟时间即为事件循环的延迟,它表示了
Node.js
从上次事件循环到当前事件循环的耗时。
1.2 perf_hooks.monitorEventLoopDelay 计算
Node.js
还提供了 perf_hooks.monitorEventLoopDelay
,这是一个专门用于监控事件循环延迟的 API
。它允许我们更高效、直接地获取事件循环延迟数据,而无需手动计算时间差。perf_hooks.monitorEventLoopDelay
:这是专为事件循环延迟设计的 API
,具有较低的性能开销,使用简单,能够高效地提供事件循环延迟数据。
const { monitorEventLoopDelay } = require('perf_hooks');
const http = require('http');
// 设置事件循环延迟监控(单位为毫秒)
const eventLoopMonitor = monitorEventLoopDelay({ resolution: 10 }); // 每10毫秒检查一次事件循环延迟
eventLoopMonitor.enable(); // 启动监控
// 创建一个 HTTP 服务器(模拟应用的负载)
http.createServer((req, res) => {
res.end('Hello, Node.js Event Loop!');
}).listen(3000, () => {
console.log('Server is running at http://localhost:3000');
});
// 每秒钟打印一次事件循环延迟
setInterval(() => {
const delay = eventLoopMonitor.mean;
console.log(`Event Loop Delay (ms): ${delay}`);
}, 1000);
-
perf_hooks.monitorEventLoopDelay
:这是一个专门用于监控事件循环延迟的工具,可以提供非常精确的事件循环延迟信息。它的默认精度为毫秒。 -
resolution
:指定了监控的精度。这里我们设置为 10 毫秒(即每10毫秒进行一次延迟测量)。 -
eventLoopMonitor.mean
:返回的是最近一次计算的事件循环延迟的平均值(单位为毫秒)。 -
通过
setInterval
每秒打印一次事件循环延迟。
1.3 process.hrtime 与 perf_hooks.monitorEventLoopDelay
要在 Node.js
中实现事件循环延迟的计算,优先使用 perf_hooks.monitorEventLoopDelay
,如果不支持则降级为 process.hrtime()
const { performance, monitorEventLoopDelay } = require('perf_hooks');
// 默认的事件循环延迟计算方法
function calculateEventLoopLagUsingHrtime() {
const start = process.hrtime();
process.nextTick(() => {
const delta = process.hrtime(start);
const lag = delta[0] + delta[1] / 1e9; // 转换为秒
console.log(`Event loop lag (using hrtime): ${lag} seconds`);
});
}
// 事件循环延迟计算方法
function calculateEventLoopLag() {
// 检查 perf_hooks 是否可用,优先使用 monitorEventLoopDelay
if (monitorEventLoopDelay) {
const histogram = monitorEventLoopDelay();
histogram.enable(); // 启动事件循环延迟监控
setInterval(() => {
const minLag = histogram.min / 1e9; // 转换为秒
const maxLag = histogram.max / 1e9; // 转换为秒
const meanLag = histogram.mean / 1e9; // 转换为秒
console.log(`Event loop lag (min): ${minLag} seconds`);
console.log(`Event loop lag (max): ${maxLag} seconds`);
console.log(`Event loop lag (mean): ${meanLag} seconds`);
histogram.reset(); // 重置统计数据
}, 1000); // 每秒输出一次
} else {
// 如果 monitorEventLoopDelay 不可用,使用 process.hrtime 计算延迟
setInterval(calculateEventLoopLagUsingHrtime, 1000);
}
}
// 调用计算事件循环延迟
calculateEventLoopLag();
-
perf_hooks.monitorEventLoopDelay
:monitorEventLoopDelay
是perf_hooks
提供的一个API
,用于监控事件循环的延迟,它提供了精确的统计数据:min
(最小延迟)、max
(最大延迟)、mean
(平均延迟)等。如果monitorEventLoopDelay
可用,则创建一个histogram
实例,并启动事件循环延迟监控。每秒钟输出当前事件循环的最小、最大和平均延迟,并重置统计数据。 -
如果
monitorEventLoopDelay
不可用,则使用process.hrtime
,process.hrtime
提供了一个高精度的时间差计算方法,单位为纳秒。我们通过在process.nextTick
中调用它,测量每次事件循环的延迟时间。每秒计算一次延迟并输出结果。