如何在 node.js 中检测和测量事件循环阻塞?
How to detect and measure event loop blocking in node.js?
我想监控 node.js 中事件循环的每个 运行 需要多长时间。但是我不确定衡量这一点的最佳方法。我能想出的最好方法是这样的:
var interval = 500;
var interval = setInterval(function() {
var last = Date.now();
setImmediate(function() {
var delta = Date.now() - last;
if (delta > blockDelta) {
report("node.eventloop_blocked", delta);
}
});
}, interval);
我基本上是通过查看 setInterval
的延迟来推断事件循环 运行 的时间。我在 blocked 节点模块中看到了相同的方法,但感觉不准确且笨重。有没有更好的方法来获取这些信息?
更新:将代码更改为使用 setImmediate
,如 hapi.js 所做的那样。
您可能还想查看 node
和 io.js
中内置的分析。例如,参见这篇文章 http://www.brendangregg.com/flamegraphs.html
以及这个相关的 SO 答案 How to debug Node.js applications
"Is there a better way to get this information?"
我没有比检查 SetImmediate 的时间延迟更好的方法来测试事件循环,但是使用节点的高分辨率计时器而不是 Date.now()
可以获得更好的精度
var interval = 500;
var interval = setInterval(function() {
var last = process.hrtime(); // replace Date.now()
setImmediate(function() {
var delta = process.hrtime(last); // with process.hrtime()
if (delta > blockDelta) {
report("node.eventloop_blocked", delta);
}
});
}, interval);
注意:delta 将是一个元组数组 [seconds, nanoseconds]。
有关 process.hrtime() 的更多详细信息:
https://nodejs.org/api/all.html#all_process_hrtime
"The primary use is for measuring performance between intervals."
代码
此代码将测量事件循环触发所花费的时间(以纳秒为单位)。它测量当前进程和下一个滴答之间的时间。
var time = process.hrtime();
process.nextTick(function() {
var diff = process.hrtime(time);
console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);
// benchmark took 1000000527 nanoseconds
});
编辑:添加说明,
process.hrtime([时间])
Returns [seconds, nanoseconds] 元组数组中的当前高分辨率实时。 time 是一个可选参数,它必须是先前 process.hrtime() 调用的结果(因此,包含先前时间的 [seconds, nanoseconds] 元组数组中的实时时间)与当前时间不同。这些时间与过去的任意时间相关,与一天中的时间无关,因此不受时钟漂移的影响。主要用途是测量间隔之间的性能。
process.nextTick(回调[ arg][ ...])
一旦当前事件循环运行完成,调用回调函数。
这不是 setTimeout(fn, 0) 的简单别名,它的效率要高得多。它在事件循环的后续滴答中触发任何其他 I/O 事件(包括计时器)之前运行。
看看这个插件https://github.com/tj/node-blocked我现在正在使用它,它似乎可以满足您的需求。
let blocked = require("blocked");
blocked(ms => {
console.log("EVENT LOOP Blocked", ms);
});
将打印出事件循环被阻塞的时间(以毫秒为单位)
我想监控 node.js 中事件循环的每个 运行 需要多长时间。但是我不确定衡量这一点的最佳方法。我能想出的最好方法是这样的:
var interval = 500;
var interval = setInterval(function() {
var last = Date.now();
setImmediate(function() {
var delta = Date.now() - last;
if (delta > blockDelta) {
report("node.eventloop_blocked", delta);
}
});
}, interval);
我基本上是通过查看 setInterval
的延迟来推断事件循环 运行 的时间。我在 blocked 节点模块中看到了相同的方法,但感觉不准确且笨重。有没有更好的方法来获取这些信息?
更新:将代码更改为使用 setImmediate
,如 hapi.js 所做的那样。
您可能还想查看 node
和 io.js
中内置的分析。例如,参见这篇文章 http://www.brendangregg.com/flamegraphs.html
以及这个相关的 SO 答案 How to debug Node.js applications
"Is there a better way to get this information?"
我没有比检查 SetImmediate 的时间延迟更好的方法来测试事件循环,但是使用节点的高分辨率计时器而不是 Date.now()
var interval = 500;
var interval = setInterval(function() {
var last = process.hrtime(); // replace Date.now()
setImmediate(function() {
var delta = process.hrtime(last); // with process.hrtime()
if (delta > blockDelta) {
report("node.eventloop_blocked", delta);
}
});
}, interval);
注意:delta 将是一个元组数组 [seconds, nanoseconds]。
有关 process.hrtime() 的更多详细信息: https://nodejs.org/api/all.html#all_process_hrtime
"The primary use is for measuring performance between intervals."
代码
此代码将测量事件循环触发所花费的时间(以纳秒为单位)。它测量当前进程和下一个滴答之间的时间。
var time = process.hrtime();
process.nextTick(function() {
var diff = process.hrtime(time);
console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);
// benchmark took 1000000527 nanoseconds
});
编辑:添加说明,
process.hrtime([时间])
Returns [seconds, nanoseconds] 元组数组中的当前高分辨率实时。 time 是一个可选参数,它必须是先前 process.hrtime() 调用的结果(因此,包含先前时间的 [seconds, nanoseconds] 元组数组中的实时时间)与当前时间不同。这些时间与过去的任意时间相关,与一天中的时间无关,因此不受时钟漂移的影响。主要用途是测量间隔之间的性能。
process.nextTick(回调[ arg][ ...])
一旦当前事件循环运行完成,调用回调函数。
这不是 setTimeout(fn, 0) 的简单别名,它的效率要高得多。它在事件循环的后续滴答中触发任何其他 I/O 事件(包括计时器)之前运行。
看看这个插件https://github.com/tj/node-blocked我现在正在使用它,它似乎可以满足您的需求。
let blocked = require("blocked");
blocked(ms => {
console.log("EVENT LOOP Blocked", ms);
});
将打印出事件循环被阻塞的时间(以毫秒为单位)