web-dev-qa-db-ja.com

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 ノードモジュールで同じアプローチを見てきましたが、不正確で重いと感じています。この情報にアクセスするためのより良い方法はありますか?

更新:hapi.jsで行われたように、setImmediateを使用するようにコードを変更しました。

18
Fabian Jakobs

「この情報を取得するためのより良い方法はありますか?」 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);

注:デルタはタプル配列[秒、ナノ秒]になります。

Process.hrtime()の詳細については: https://nodejs.org/api/all.html#all_process_hrtime

「主な用途は、インターバル間のパフォーマンスを測定することです。」

8
YoungJohn

コード

このコードは、イベントループがトリガーされるまでにかかった時間をナノ秒単位で測定します。現在のプロセスと次のティックの間の時間を測定します。

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([time])

現在の高解像度のリアルタイムを[秒、ナノ秒]タプル配列で返します。 timeはオプションのパラメーターであり、現在の時刻と比較するために、前のprocess.hrtime()呼び出し(したがって、前の時刻を含む[seconds、nanoseconds]タプル配列のリアルタイム)の結果である必要があります。これらの時間は過去の任意の時間に関連しており、時刻とは関係がないため、クロックドリフトの影響を受けません。主な用途は、間隔間のパフォーマンスを測定することです。

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

現在のイベントループターンが完了するまで実行されたら、コールバック関数を呼び出します。

これはsetTimeout(fn、0)の単純なエイリアスではなく、はるかに効率的です。イベントループの後続のティックで追加のI/Oイベント(タイマーを含む)が発生する前に実行されます。

1
Bamieh

nodeおよびio.jsに組み込まれているプロファイリングも確認することをお勧めします。たとえば、この記事を参照してください http://www.brendangregg.com/flamegraphs.html

そして、これに関連するSO回答 Node.jsアプリケーションをデバッグする方法

0
Sam Mikes

このプラグインをチェックしてください https://github.com/tj/node-blocked 私は今それを使用しています、そしてそれはあなたが望むことをしているようです。

let blocked = require("blocked");

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

イベントループがブロックされている時間をミリ秒単位で出力します

0
Joshua Ohana