本番環境でフリーズしている node.js サーバーを持っています。JSONStream 内の無限ループが原因のようです。フリーズしたサーバーのコア ダンプから取得したスタック トレースを次に示します。
1: toString [buffer.js:~392] (this=0x1e28fb6d25c9 <a Buffer>#1#,encoding=0x266ee104121 <undefined>,start=0x266ee104121 <undefined>,end=0x266ee104121 <undefined>)
2: arguments adaptor frame: 0->3
3: write [/home/deploy/node_modules/JSONStream/node_modules/jsonparse/jsonparse.js:136] (this=0x32cc8dd5a999 <a Parser>#2#,buffer=0x32cc8dd5aa49 <a Buffer>#3#)
4: /* anonymous */ [/home/deploy/node_modules/JSONStream/index.js:~17] (this=0x32cc8dd5ab11 <a Stream>#4#,chunk=0x32cc8dd5aa49 <a Buffer>#3#)
5: write [/home/deploy/node_modules/JSONStream/node_modules/through/index.js:~24] (this=0x32cc8dd5ab11 <a Stream>#4#,data=0x32cc8dd5aa49 <a Buffer>#3#)
6: write [_stream_readable.js:~582] (this=0x266ee106c91 <JS Global Object>#5#,dest=0x32cc8dd5ab11 <a Stream>#4#,i=0,list=0x266ee104101 <null>)
7: flow [_stream_readable.js:592] (this=0x266ee106c91 <JS Global Object>#5#,src=0x32cc8dd5ac69 <an IncomingMessage>#6#)
8: /* anonymous */ [_stream_readable.js:560] (this=0x266ee106c91 <JS Global Object>#5#)
9: _tickCallback [node.js:415] (this=0x29e7331bb2a1 <a process>#7#)
この無限ループの原因を見つけるにはどうすればよいですか?
残念ながら、サーバーは本番環境で稼働しており、何千ものリクエストを処理しているため、追加のコンテキストを提供することは困難です. サーバーの基本的な機能は、他のサービスに対してアウトバウンド HTTP 要求を行うことです。
これがメモリリークが原因であるとは思わないことに注意してください。これらのフリーズ イベントの間、サーバーのメモリ使用量は一定 (かつ低く) に保たれますが、CPU は 99% に急上昇します。
無限ループが終了したことを示すもう 1 つの証拠は、イベント ループ自体が停止したように見えることです。setInterval 内に console.log を配置すると、サーバーがフリーズするとすぐに出力が停止します。
最大接続数を Infinity に設定することで (node.js での再利用を無効にします)、問題の原因がソケット接続の期限切れ/破損ではないことを確認しました。
JSONStream 0.7.1 を使用しています (デフォルトの jsonparse バージョン 0.0.5 が含まれています)。JSONStream リポジトリでこの問題を発見し、JSONParse をフォークして、最新の jsonparse バージョンにのみ更新しようとしました。問題は解決しませんでした。