3

コードでメモリ リークが発生しています。数時間後、メモリ全体がいっぱいになり、クラッシュします。ここでコードを簡略化しましたが、これがリークしているように見えるかどうかを誰かが知ることができますか? ありがとう。

var request = require('request').forever(), // as per [1]
    async = require('async'),
    kue = require('kue'),
    jobs = kue.createQueue(),
    pool = { maxSockets: 1 };



function main (job, done) {
    async.series(
        [function (callback) {
            var req = request({url: job.data.URL1, pool: pool}, function (err, resp, body) {
                //stuff...
                callback(err);
            });
        },
        function (callback) {
            var req = request({url: job.data.URL2}, function (err, resp, body) {
                //stuff...
                callback(err);
            });
        }
        ],
        function (err) {
            //stuff...
            done();
        }
    );

}

jobs.process('job_name', function (job, done) {  //many jobs with 'job_name' in the queue
    main (job, done);
});

[1] https://groups.google.com/d/msg/nodejs/ZI6WnDgwwV0/sFm4QKK7ODEJ

4

2 に答える 2

1

あなたのコードに責任があるとは思いません。私は kue を使用してまったく同じ問題を抱えていました。何か間違ったことをしていないことを確認するために、次のような非常に単純なワーカーを作成しました。

var Redis       = require('redis'),
    kue         = require('kue'),
    config      = require("../../config/local.js"),
    redisClient = Redis.createClient(config.redis),
    jobs        = kue.createQueue({ redis : config.redis });

jobs.process('testjobs', function processJob(job, done, error) {
    console.log(job.data, error);
    done();
});

このコードを実行すると、これがリークしていることに気付きました。回避策はpm2を使用することです。メモリが上限に達すると、この男がプログラムを実行して再起動します。JSON アプリ宣言を使用して、プロセスを再起動する前に許可されるメモリの最大量を構成しています。

{
  "apps" : [
    {
      "name": "test_worker",
      "script": "test.js",
      "instances": 1,
      "max_restarts": 10,
      "max_memory_restart" : "10M",
      "ignore_watch": [
        "[\\/\\\\]\\./",
        "node_modules"
      ],
      "merge_logs": true,
      "exec_interpreter": "node",
      "exec_mode": "fork_mode"
    }
  ]
}

お役に立てれば。

于 2015-03-04T22:44:08.113 に答える
1

おっしゃるように、ジョブが削除されるよりも速くキューに追加されると、メモリ使用量が増加します。これは厳密にはメモリ リークではありません。これは、Kue がジョブ レベルのイベントを利用できるようにする方法の一部です。

デフォルトでは、ジョブが完了するか失敗するまで、Kue はメモリ内のジョブにハングアップします。これは、ジョブを作成したプロセスでジョブレベルのイベント (例: startprogress、 ) をトリガーできるようにするためです。completefailed

これは、現在キューにあるすべてのジョブも、それらを作成したプロセスのメモリ内に存在することを意味します (アプリケーションの再起動がない場合)。キューがバックアップされない限り、メモリが増加することはありません。ただし、キューがメモリをバックアップすると、驚くほど大きくなることがあります。

何をすべきか?ジョブ レベルのイベントをオフにすると、ジョブがキューに入れられた後、Kue はジョブにハングアップしません。jobEventsフラグを使用して、これをグローバルに行うことができます。

 kue.createQueue({jobEvents: false});

eventsまたは、ジョブのメソッドを使用して、ジョブごとにジョブレベルのイベントをオンまたはオフにすることができます。

var job = queue.create('test').events(false).save();

これらは、ジョブ イベントにまったく応答する必要がない場合に機能します。ただし、ジョブのイベントを処理する必要がある場合は、キュー レベルのイベントを使用できます。ジョブはメモリに保持されないため、何かを行うには redis からジョブを取得する必要があります。

queue.on('job complete', function(id, result){
  kue.Job.get(id, function(err, job){
    // do something with the job
  });
});
于 2016-07-04T17:16:05.950 に答える