【发布时间】:2013-12-21 08:32:55
【问题描述】:
查看nodejs域文档页面中给出的示例:http://nodejs.org/api/domain.html,建议使用集群重启worker的方法是在worker部分调用first 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 处执行获取请求
- 计时器已启动:30 秒后该进程将被杀死(如果尚未终止)
- http 服务器已关闭
- worker 已断开连接(但仍然存在)
- 显示500页
-
我在错误时执行了第二次获取请求(30 秒之前)
- 新计时器已启动
- 服务器已经关闭 => 抛出错误
- 错误在“catch”块中被捕获,没有结果返回给客户端,所以在客户端,页面正在等待,没有任何消息。
在我看来,最好干掉worker,然后在master部分听'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 在服务器实际结束关闭之前执行了第二个请求。
在这种情况下,服务器正在关闭而不是关闭(这意味着工作人员也在断开连接但没有断开连接),导致第二个请求与之前一样由同一个工作人员处理:
- 它阻止服务器完成关闭
- 第二个
server.close();行被评估,它触发一个异常,因为服务器没有关闭。
- 在调用 killtimer 回调之前,所有后续请求都将触发相同的异常。
【问题讨论】:
-
我遇到了同样的问题,断开连接的工作人员仍然收到请求并且没有关闭。我注意到工作人员在
killTimer到期后关闭,而这不应该发生,因为我们unref计时器并刚刚完成应该终止工作人员的正常过程。就像 Node.js 文档中所说的那样: // 但不要仅仅为此而保持进程打开!killtimer.unref(); -
认为它可能取决于节点版本,我无法在link 使用完全相同的代码重现该问题:我的节点版本是 0.10.22(我刚刚更新)可运行节点版本是0.10.12
标签: javascript node.js cluster-computing node.js-domains