在查看nodejs领域文档页面上给出的示例时:http://nodejs.org/api/domain.html,使用集群重启工作进程的推荐方式是在worker部分首先调用disconnect方法,并在master部分监听disconnect事件。然而,如果您只是复制/粘贴给出的示例,您会注意到disconnect()调用并没有关闭当前的worker:
这里发生的情况是:
try {
var killtimer = setTimeout(function() {
process.exit(1);
}, 30000);
killtimer.unref();
server.close();
cluster.worker.disconnect();
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.end('Oops, there was a problem!\n');
} catch (er2) {
console.error('Error sending 500!', er2.stack);
}
我在 /error 发送一个 get 请求
- 启动一个计时器:如果在 30 秒内没有完成,进程将被强制关闭
- 关闭 http 服务器
- 断开工作进程的连接(但仍然存活)
- 显示 500 错误页面
我在 30 秒内再次发送了一个 get 请求到 error
- 启动一个新的计时器
- 服务器已经关闭 => 抛出错误
- 在 "catch" 块中捕获错误,并且不向客户端返回任何结果,因此在客户端上,页面一直等待而没有任何消息。
我认为最好的方法是直接杀死工作进程,并在主进程部分监听 'exit' 事件来重新 fork。这样,在发生错误时,总是会发送 500 错误:
try {
var killtimer = setTimeout(function() {
process.exit(1);
}, 30000);
killtimer.unref();
server.close();
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.end('Oops, there was a problem!\n');
cluster.worker.kill();
} catch (er2) {
console.error('Error sending 500!', er2);
}
我不确定使用kill而不是disconnect的负面影响,但似乎disconnect正在等待服务器关闭,然而它似乎没有起作用(至少不像应该的那样)。我只想听听这方面的反馈。可能有一个我错过的很好的原因,这个例子是这样写的。谢谢。
编辑:
我刚刚用curl检查了一下,它工作得很好。 然而,我之前是用Chrome进行测试的,似乎在发送500响应后,Chrome会在服务器实际结束关闭之前发出第二个请求。 在这种情况下,服务器正在关闭而没有关闭(这意味着工作程序也在断开连接而没有被断开连接),导致第二个请求由之前的同一工作程序处理,从而: 1. 阻止服务器完成关闭 2. 第二个server.close();行被评估,它触发一个异常,因为服务器没有关闭。 3. 所有后续请求都将触发相同的异常,直到killtimer回调被调用。
killTimer
过期后,工作进程会关闭,而这不应该发生,因为我们已经使用unref
取消引用计时器,并且只是完成正常的进程,这应该终止工作进程。就像Node.js文档所述://但不要仅仅为此保持进程处于打开状态!killtimer.unref();
- Manuras