問題
リクエストモジュールを備えたNodeJSサーバーがあります。ファイルを提供するためにリクエスト を使用pipe()
します。
時々、アプリが例外をスローし、すべてのダウンロードがキャンセルされ、アプリを再起動する必要があります:
メモリ不足: プロセス 9342 (nodejs) スコア 793 を強制終了するか、子を犠牲にし
ます プロセス 9342 (nodejs) を強制終了します
サーバーが予期せず終了したときに (childprocess と fork を使用して) 自動的に再起動する別のスクリプトを作成しましたが、このエラーがスローされることがあります。
致命的なエラー: CALL_AND_RETRY_2 割り当てに失敗しました - プロセスがメモリ不足です
サーバー データ
RAM: 500MB (これは多くないことはわかっていますが、安価です)
Ubuntu 12.04.5 LTS
NodeJS バージョン: v0.10.36
仮定
- 並行ダウンロードが多すぎる
- RAMに関連するパイプに問題があります
1について:
誰かが大きなファイルをダウンロードすると、その一部がRAMにロードされます(これについては何も知りません。一度に20MBと言います。間違っている場合は修正してください)。400MB が利用可能で、同じダウンロード速度で 20 の現在のダウンロードがある場合、RAM に一度に 400MB 以上をロードできないため、サーバーがクラッシュします。
2 について:
さらにpipe()
、次のコードを使用して、現在のダウンロードとキャンセルされたダウンロードを追跡します。
req.on("close", function() {
currentDownloads--;
});
が正しく閉じず、pipe()
使用していた RAM がクリアされません。
質問
私の仮定のいずれかが正しい場合、どうすればそれを修正できますか? そうでない場合、原因はどこにあるのでしょうか(NodeJS/リクエストモジュール/コードが間違っているか悪いか、より良い方法はありますか)?
完全なコード
var currentDownloads = 0;
app.post("/", function (req, res) {
var open = false;
req.on("close", function () {
if (open) {
currentDownloads--;
open = false;
}
});
request.get(url)
.on("error", function (err) {
log("err " + err);
if (open) {
currentDownloads--;
open = false;
}
})
.on("response", function () {
open = true;
currentDownloads++;
})
.pipe(res);
});