この問題により、本番サーバーの安定性が損なわれています。
要約すると、基本的な考え方は、ノード サーバーが断続的に遅くなり、ゲートウェイ タイムアウトが発生することがあるということです。私のログからわかる限り、何かがノード スレッドをブロックしています (つまり、着信要求が受け入れられないことを意味します) が、何が原因であるかを突き止めることはできません。
問題の重大度はさまざまです。100 ミリ秒未満のリクエストが完了するまでに最大 10 秒かかる場合があります。ノードサーバーにまったく受け入れられないこともあります。要するに、ランダムなタスクが動作し、一定期間ノード スレッドをブロックしているように見えます。確かに言えることは、修正が必要な症状は「ゲートウェイタイムアウト」であるということです。
この問題は予告なしに行き来します。CPU 使用率、RAM 使用率、稼働時間、またはその他の関連する統計と関連付けることができませんでした。サーバーが大きな負荷を正常に処理し、小さな負荷でこのエラーが発生するのを見たので、負荷に関連しているようには見えません. 1 日の最小ロード時間である PST の午前 1 時頃にエラーが表示されることは珍しくありません。ノードアプリを再起動すると、問題がしばらく解消されるようですが、実際にはあまりわかりません. それはnode.jsのバグではないかと思います...本番サーバーが停止していることを考えると、あまり安心できません。
- 私が最初にしたことは、node.js を最新 (0.8.12) にアップグレードしたことと、すべてのモジュール (ここにある) を確認することでした。もちろん、エラーキャッチャーもたくさん用意しています。コンソールに大量に出力したり、大量のファイルに書き込んだりするようなおかしなことはしていません。
- Expressミドルウェアがインバウンドリクエストを拾っていないので、最初はアウトバウンドHTTPリクエストがインバウンドソケットをブロックしていると思っていましたが、ノードスレッド自体がビジーになったように見えるため、理論を断念しました。
- 次に、JSHint を使用してすべてのコードを調べ、いくつかの偶発的なグローバル (「var」を書き忘れた) を含め、文字通りすべての警告を修正しましたが、これは役に立ちませんでした。
- その後、おそらくメモリが不足していると思いました。しかし、nodetime を介したヒープ スナップショットは、かなり良好に見えます (以下で説明します)。
- まだメモリが問題かもしれないと考えて、ガベージコレクションを調べました。--nouse-idle-notification フラグを有効にし、必要のない NULL オブジェクトに対してさらにコードの最適化を行いました。
- 問題はメモリにあると確信していたので、 --expose-gc フラグを追加して gc(); を実行しました。毎分コマンド。これは、おそらくリクエストを少し遅くすることを除いて、何も変更しませんでした.
- 必死の試みで、2 つのワーカーを使用して 30 分ごとに自動的に再起動するように「クラスター」モジュールをセットアップしました。それでも、運が悪い。
- ulimit を 10,000 以上に増やし、開いているファイルを監視しました。node.js アプリごとに 300 個未満の開いているファイル (またはソケット) があるようで、ulimit を増やしても影響はありませんでした。
私は自分のサーバーをノードタイムでログに記録してきましたが、その要旨は次のとおりです。
- Amazon クラウドで実行されている CentOS 5.2 (m1.large インスタンス)
- 常に 5000 MB を超える空きメモリ
- 常に 150 MB 未満のヒープ サイズ
- CPU 使用率は常に 60% 未満です
また、CPU 使用率が 5% 未満で、完了までに 100 ミリ秒を超えるリクエストがない MongoDB サーバーも確認したので、ボトルネックがあるとは思えません。
Q-promise を使用して (ほぼ) すべてのコードをラップし (コード サンプル を参照)、もちろん疫病のような Sync() 呼び出しを回避しました。テスト サーバー (OSX) で問題を再現しようとしましたが、うまくいきませんでした。もちろん、これは、運用サーバーが非常に多くの人々によって予測不可能な方法で使用されているためであり、ストレス テストで再現することはできません...