在Node.js集群中,当工作进程被主进程杀死时,会触发“exit”事件。

4
我想要从主进程优雅地退出子进程,其中主进程和子进程的代码位于不同的.js文件中。 master.js
cluster.setupMaster({
  exec : 'child.js',
  args : [],
  silent : false
});
cluster.fork({'some': 'info'});

process.on('SIGINT', function() {
  console.log('\nshutting down services ...');
  function eachWorker(callback) {
    for (var id in cluster.workers) {
      callback(cluster.workers[id]);
    }
  }
  eachWorker(function(worker) {
    worker.kill();
  });
  process.exit(0);
})

child.js

cluster.worker.on('disconnect', function() {
  console.log(cluster.worker.id + ' shutting down.');
})

我尝试了各种信号,如cluster.worker.on('exit')、process.on('exit')、process.on('disconnect')等,但似乎都没有触发。有什么想法吗?
worker.send()在执行期间有效,但在SIGINT函数中无效?
1个回答

5
Node.js(或我的Mac)似乎在处理ctrl-c和SIGINT时略有不同。当我按下ctrl-c时,两个子进程都会被强制退出,然后主进程退出。如果我在后台启动master.js并执行kill -SIGINT [pid],则代码将正确执行,子进程将收到通知,世界一切都好。
有几种方法可以解决这种情况。第一种是实际上使用SIGINT而不是ctrl-c进行杀死。第二种是在子进程中添加process.on('SIGINT')。像这样的简单操作:
process.on('SIGINT', function() {
    console.log('\nshutting down ...');
    setTimeout(function() { console.log('quitting'); process.exit(0); }, 10000);
});
将给孩子们足够的时间来适当关闭。(显然,目标是在给定的10秒内退出)
要在客户端处理消息,您需要:
var cluster = require('cluster');
var worker = cluster.worker;
worker.on('message', function(msg) {
        console.log("message for worker: " );
        console.log(msg);
        if (msg == "exit) ...
});
eachWorker(function...中:
worker.send("exit");
这实际上可能是node.js中的一个错误。集群仍处于“实验性”状态。

我已经添加了一些关于生成的信息。当我将worker.send()放在master.js代码的某个位置时,它可以工作,但是在SIGINT过程中却不行。 - Patrick
尝试了几个方法后,我得出了相同的结论。你可以使用cluster.disconnect([callback])代替消息,在所有工作进程断开连接后继续进行。看起来是有效的。 - Patrick
1
这对于使用express clusters的gulp-nodemon非常有帮助。 - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接