Node は、サーバー側の Javascript のランタイムとして、JavaScript のアプリケーション シナリオを大幅に強化します。
しかし、Node.js ランタイム自体はブラックボックスであり、ランタイムの状態を認識することができず、オンライン上での問題を再現することは困難です。
したがって、パフォーマンスの監視は、Node.js アプリケーションの「通常の動作」の基礎となります。さまざまな実行時インジケーターをいつでも監視できるだけでなく、異常なシナリオの問題のトラブルシューティングにも役立ちます。
パフォーマンス監視は、パフォーマンス インジケータの収集と表示の 2 つの部分に分けることができます
。
パフォーマンス データのキャプチャと分析
上の図から、現在主流の 3 つの Node.js パフォーマンス監視ソリューションの長所と短所がわかります。以下に、これら 3 つのソリューションの構成を簡単に紹介します。
Prometheus
AliNode を形成するための問題のトラブルシューティングにのみ必要です。
Alinode は、公式の Nodejs と互換性のある拡張ランタイムであり、いくつかの追加機能を提供します:
は、パフォーマンス インジケーターを収集するために使用される常駐プロセスです。
、
監視、表示、スナップショット、分析までの閉ループを形成しますが、
Easy-Monitor
Node.js Addon
現在のプロセスの CPU 時間消費データはprocess.cpuUsage()
戻り値の単位はマイクロ秒です。
現在のプロセスのメモリ割り当てデータはprocess.memoryUsage()
を通じて取得できます。戻り値の単位はバイトです。
上の図からわかるように、 rss
はコード セグメント ( Code Segment
)、スタック メモリ ( Stack
)、およびヒープ メモリ ( Heap
) が含まれています。
v8.getHeapStatistics()
およびv8.getHeapSpaceStatistics()
次の図は、v8 のヒープ メモリ構成の分布を示しています。
ヒープ メモリ空間はまずスペースに分割され、そのスペースは 1MB のアライメントに従ってページ化されます。
新しいスペース: 新しい世代のスペース。ライフ サイクルが比較的短いオブジェクト データを保存するために使用され、2 つのスペース (スペース タイプはsemi space
) に分割されます。 from space
to space
古いスペース: New Space
によってプロモートされたオブジェクトを格納するために使用される古い世代スペース
コード スペース: v8 JIT によってコンパイルされた実行可能コードを格納します。
マップ スペース: Object が指す隠しクラスのポインター オブジェクトを格納します。ランタイムに応じて、オブジェクト レイアウト構造は、オブジェクト メンバーに迅速にアクセスするために使用されます。
ラージ オブジェクト スペース: ページに割り当てられない 1MB を超えるオブジェクトを格納するために使用さ
ます
Mark-Sweep-Compact
アルゴリズムを使用します。Scavenge
前提: New space
、 from
とto
トリガーのタイミング: New space
がいっぱいになったとき。
手順:
from space
で、幅優先の走査を実行し
、生き残った (到達可能な) オブジェクトが
Old space
とto space
to space
が終了すると、 from space
スペースが空になり、
from space
からto space
の交換が行われ、次のラウンドScavenge
が開始されます。
頻繁なリサイクルやメモリ不足に適しています。大きなオブジェクトの場合、一般的なスペースフォータイム戦略には、
3 つのステップ: マーキング、クリア、整理
トリガー タイミング: Old space
がいっぱいになったとき
ステップ:
マーキング (3 色マーキング方法)。
marking queue
(明示的スタック) に入れ、これらのオブジェクトをグレーとしてマークします。marking queue
からpop
て黒にマークしmarking queue
にpush
スイープは
。コンパクト
Old space
v8 が最初にガベージ コレクションを実行するときは、プログラムを再実行する前にプログラムを停止し、ヒープ全体をスキャンし、メモリを再利用する必要があります。この動作は完全停止 ( Stop-The-World
) と呼ばれます
が、新しい世代のアクティブなオブジェクトは小さく、頻繁にリサイクルされますが、完全な停止はほとんど影響を与えません。マーキング、クリーニング、仕分けなどによる一時停止も発生します。さらに深刻になります。
この概念は、実際には React フレームワークのファイバー アーキテクチャに似ています。ブラウザーの空き時間中のみファイバー ツリーを通過して、対応するタスクを実行します。それ以外の場合、実行は遅延し、メイン スレッドのタスクへの影響は最小限に抑えられます。 、アプリケーションの遅延を回避し、アプリケーションのパフォーマンスを向上させます。
v8 には新世代と旧世代のスペースにデフォルト制限があるため、
New space
デフォルト制限は 64 ビット システムの場合は 32M、Old space
デフォルト制限は 64 ビット システムの場合は 1400M ですしたがって、 node
新世代と旧世代のスペースの上限を調整するために 2 つのパラメーターが提供されます
--max-semi-space-size
: New Space
のスペース--max-old-space-size
--max-old-space-size
: Old Space
の最大値を設定します spacenode
は、GC ログを表示する 3 つの方法もあります:
--trace_gc
: ログの 1 行に、各 GC の時間、タイプ、ヒープ サイズの変更と原因が簡単に説明されます--trace_gc_verbose
: 各 GC 後の各 V8 ヒープを表示します。スペースの詳細なステータス--trace_gc_nvp
: GC タイプ、一時停止時間、メモリ変更などを含む、各 GC の詳細なキーと値のペア情報。GCログは比較的原始的であり、必要な情報を必要とします
。二次処理には、AliNode チームが開発した v8-gc を使用できます。Heapsnapshot
実行中のプログラムのヒープ メモリのスナップショットを取得し、メモリ消費を分析し、
Heapsnapshot ファイルのできます.heapsnapshot
次の方法で生成されます:
heapdump を使用する
v8 のヒープ プロファイルの使用
Nodejs の組み込み v8 モジュールによって提供される
APIv8.getHeapSnapshot()
v8.writeHeapSnapshot(fileName)
v8-profiler-next の使用
、Chrome devtools ツールバーのメモリにアップロード.heapsnapshot
、結果は次のように表示されます。
デフォルトのビューはSummary
ビューです。ここでは、右端の 2 つの列に注意する必要があります: Shallow Size
Retained Size
Shallow Size
v8 ヒープ メモリに割り当てられたオブジェクト自体のサイズを示しますRetained Size
オブジェクトのすべての参照オブジェクトのShallow Size
Retained Size
大きいことが判明した場合、オブジェクト内でメモリ リークが発生している可能性があるため、
Comparison
ビューを使用して比較
2 つの異なる期間のヒープ スナップショットを分析する場合、 Delta
列を使用して、メモリ変更が最も大きいオブジェクトを除外できます。
、プログラムを実行しているCPU のスナップショット サンプリングを実行します。これは、CPU 時間と割合を分析するために使用できます。
.cpuprofile
ファイルを生成するには、いくつかの方法があります。
これは 5 分間の CPU プロファイル サンプル コレクションです
。Javascript Profiler
生成された.cpuprofile
ファイルは、
デフォルトのビューはHeavy
ビューです。ここではSelf Time
とTotal Time
Total Time
実行時間を表しますSelf Time
他の呼び出しを除く)。アプリケーションが予期せずクラッシュして終了した場合は、
Self Time
Total Time
シューティングを行うこともできます
システムはそれを自動的に記録します。プロセスはその時点でメモリ割り当て情報、プログラム カウンター、スタック ポインター、およびその他の重要な情報をクラッシュし
、.core ファイルを.core
3 つの方法:
ulimit -c unlimited
カーネル制限を開きます。node --abort-on-uncaught-exception
の起動時にこのパラメータを追加すると、アプリケーションでキャッチされない例外が発生したときにコア ファイルを生成できます。gcore <pid>
.core
ファイルを取得した後、解析と解析
診断は、mdb、gdb、lldb などのツールを通じて行うことができます。 プロセス クラッシュの実際の原因
llnode `which node` -c /path/to/core/dump
監視すると、ヒープ メモリが増加し続けていることがわかります。そのため、トラブルシューティング
heapsnapshot
分析すると、比較的大きなメモリを常に保持しているnewThing
オブジェクトが存在することがわかります
newThing
theThing
unused
クロージャによって引き起こされるreplaceThing
のケースには、
などの状況が含まれます
。したがって、上記の状況では、メモリ内のオブジェクトが自動的にリサイクルされるかどうかを慎重に検討する必要があります。自動的にリサイクルされない場合は、オブジェクトを手動でnull
に設定する、タイマーを削除する、イベント リスナーをバインド解除するなど、手動でリサイクルする必要があります。
、Node.js パフォーマンス監視システム全体について詳しく説明しました。
まず、パフォーマンス監視によって解決される問題、そのコンポーネント、および主流のソリューションの長所と短所の比較を紹介します。
次に、パフォーマンス インジケーターとスナップショット ツールの 2 つの主要な部分を詳細に紹介します。
最後に、観察、分析、トラブルシューティングから単純なメモリ リークのケースを再現し、一般的なメモリ リークの状況と解決策をまとめます。
この記事が、皆さんが Node.js パフォーマンス監視システム全体を理解するのに役立つことを願っています。