How to detect and measure event loop blocking in node.js?

元气小坏坏 提交于 2019-11-29 00:59:36

问题


I'd like to monitor how long each run of the event loop in node.js takes. However I'm uncertain about the best way to measure this. The best way I could come up with looks like this:

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);

I basically infer the event loop run time by looking at the delay of a setInterval. I've seen the same approach in the blocked node module but it feels inaccurate and heavy. Is there a better way to get to this information?

Update: Changed the code to use setImmediate as done by hapi.js.


回答1:


"Is there a better way to get this information?" I don't have a better way to test the eventloop than checking the time delay of SetImmediate, but you can get better precision using node's high resolution timer instead of 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);

NOTE: delta will be a tuple Array [seconds, nanoseconds].

For more details on process.hrtime(): https://nodejs.org/api/all.html#all_process_hrtime

"The primary use is for measuring performance between intervals."




回答2:


Code

this code will measure the time in nanoseconds it took for the event loop to trigger. it measures the time between the current process and the next tick.

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
});

EDIT: added explanation,

process.hrtime([time])

Returns the current high-resolution real time in a [seconds, nanoseconds] tuple Array. time is an optional parameter that must be the result of a previous process.hrtime() call (and therefore, a real time in a [seconds, nanoseconds] tuple Array containing a previous time) to diff with the current time. These times are relative to an arbitrary time in the past, and not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals.

process.nextTick(callback[, arg][, ...])

Once the current event loop turn runs to completion, call the callback function.

This is not a simple alias to setTimeout(fn, 0), it's much more efficient. It runs before any additional I/O events (including timers) fire in subsequent ticks of the event loop.




回答3:


Check out this plugin https://github.com/tj/node-blocked I'm using it now and it seems to do what you want.

let blocked = require("blocked");

blocked(ms => {
  console.log("EVENT LOOP Blocked", ms);
});

Will print out how long in ms the event loop is blocked for




回答4:


You may also want to look at the profiling built into node and io.js. See for example this article http://www.brendangregg.com/flamegraphs.html

And this related SO answer How to debug Node.js applications



来源:https://stackoverflow.com/questions/28563354/how-to-detect-and-measure-event-loop-blocking-in-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!