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 App Declaration来配置在重新启动进程之前允许的最大内存量。

{
  "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 会挂在内存中的作业上,直到作业完成或失败。它这样做是为了在创建作业的进程中触发作业级事件(例如startprogresscompletefailed)。

这意味着当前队列中的所有作业也都存在于创建它们的进程的内存中(假设没有应用程序重新启动)。只要队列没有得到备份,你就不会看到内存增长。但是,如果队列备份内存增长,有时会令人担忧。

该怎么办?如果您关闭作业级事件,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 回答