我在 Heroku 上搭建了一个相当简单的系统。我使用 RabbitMQ 处理后台工作。我的设置包括使用 Heroku Scheduler 插件每天运行一个节点脚本。该脚本将作业添加到队列中,工作者进而消耗它们并委派给一个独立模块进行处理。
问题是,在我随机收到 SIGTERM 事件之后,Heroku 突然重新启动实例之前,就开始出现问题了。
由于某种原因,在实例重新启动之后,工作者再也无法恢复正常工作。只有当我手动执行 heroku ps:scale worker=0
和 heroku 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);