在NodeJS工作器重新启动Heroku后恢复排队的作业

时间:2016-09-21 07:37:55

标签: node.js heroku rabbitmq jobs sigterm

所以我在 Heroku 上有一个相当简单的设置。我使用 RabbitMQ 来处理后台作业。我的设置包含一个每天使用 Heroku Scheduler 插件运行的节点脚本。脚本将作业添加到队列中,工作者依次使用它们并将它们委托给单独的模块进行处理。

在重新启动实例之前,我收到 Heroku 不时随机启动的 SIGTERM 事件后,问题就开始了。

由于某种原因,在重新启动实例后,工作人员永远不会再次恢复。仅当我通过执行heroku ps:scale worker=0heroku ps:scale worker=1手动重新启动它时,工作人员继续使用待处理的作业。

这是我的工人:

// worker.js
var throng = require('throng');
var jackrabbit = require('jackrabbit');
var logger = require('logfmt');
var syncService = require('./syncService');

var start = function () {
    var queue = jackrabbit(process.env.RABBITMQ_BIGWIG_RX_URL || 'amqp://localhost');

    logger.log({type: 'msg', msg: 'start', service: 'worker'});

     queue
        .default()
        .on('drain', onDrain)
        .queue({name: 'syncUsers'})
        .consume(onMessage)

    function onMessage(data, ack, nack) {

        var promise;
        switch (data.type) {
            case 'updateUser':
                promise = syncService.updateUser(data.target, data.source);
                break;
            case 'createUser':
                promise = syncService.createUser(data.source);
                break;
            case 'deleteUser':
                promise = syncService.deleteUser(data.target);
        }

        promise.then(ack, nack);
    }

    function onDrain() {
        queue.close();
        logger.log({type: 'info', msg: 'sync complete', service:    'worker'});
     }

    process.on('SIGTERM', shutdown);


    function shutdown() {
        logger.log({type: 'info', msg: 'shutting down'});
        queue.close();
        process.exit();
    }

};


throng({
    workers: 1,
    lifetime: Infinity,
    grace: 4000
}, start);

1 个答案:

答案 0 :(得分:1)

close()对象takes a callback上的jackrabbit方法,您应该避免退出该流程,直到完成:

function shutdown() {
    logger.log({type: 'info', msg: 'shutting down'});
    queue.close(function (e) {
      process.exit(e ? 1 : 0);
    });
}