1

問題

リクエストモジュールを備えたNodeJSサーバーがあります。ファイルを提供するためにリクエスト を使用pipe()します。

時々、アプリが例外をスローし、すべてのダウンロードがキャンセルされ、アプリを再起動する必要があります:

メモリ不足: プロセス 9342 (nodejs) スコア 793 を強制終了するか、子を犠牲にし
ます プロセス 9342 (nodejs) を強制終了します

サーバーが予期せず終了したときに (childprocess と fork を使用して) 自動的に再起動する別のスクリプトを作成しましたが、このエラーがスローされることがあります。

致命的なエラー: CALL_AND_RETRY_2 割り当てに失敗しました - プロセスがメモリ不足です


サーバー データ
RAM: 500MB (これは多くないことはわかっていますが、安価です)
Ubuntu 12.04.5 LTS

NodeJS バージョン: v0.10.36

仮定

  1. 並行ダウンロードが多すぎる
  2. 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);
});
4

0 に答える 0