查看 nodejs 域文档页面中给出的示例:http://nodejs.org/api/domain.html ,使用集群重启worker的推荐方法是先在worker部分调用disconnect,然后在master部分监听disconnect事件。但是,如果您只是复制/粘贴给定的示例,您会注意到 disconnect() 调用不会关闭当前工作人员:
这里发生的是:
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 秒之前)
- 新计时器开始
- 服务器已经关闭 => 抛出一个错误
- 错误在“catch” block 中被捕获,并且没有结果发送回客户端,因此在客户端,页面正在等待,没有任何消息。
在我看来,最好直接杀死 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 在服务器实际结束关闭之前执行了第二个请求。
在这种情况下,服务器正在关闭而不是关闭(这意味着 worker 也在断开连接而不是断开连接),导致第二个请求由与之前相同的 worker 处理所以:
- 它阻止服务器完成关闭
- 正在评估第二个
server.close();
行,它触发异常,因为服务器未关闭。 - 所有后续请求将触发相同的异常,直到调用 killtimer 回调。
最佳答案
我想通了,实际上当服务器关闭的同时收到一个请求,它停止了它的关闭过程。
所以他仍然接受连接,但不能再关闭。
即使没有集群,这个简单的例子也说明了这一点:
var PORT = 8080;
var domain = require('domain');
var server = require('http').createServer(function(req, res) {
var d = domain.create();
d.on('error', function(er) {
try {
var killtimer = setTimeout(function() {
process.exit(1);
}, 30000);
killtimer.unref();
console.log('Trying to close the server');
server.close(function() {
console.log('server is closed!');
});
console.log('The server should not now accepts new requests, it should be in "closing state"');
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);
}
});
d.add(req);
d.add(res);
d.run(function() {
console.log('New request at: %s', req.url);
// error
setTimeout(function() {
flerb.bark();
});
});
});
server.listen(PORT);
只需运行:
curl http://127.0.0.1:8080/ http://127.0.0.1:8080/
输出:
New request at: /
Trying to close the server
The server should not now accepts new requests, it should be in "closing state"
New request at: /
Trying to close the server
Error sending 500! [Error: Not running]
现在单个请求:
curl http://127.0.0.1:8080/
输出:
New request at: /
Trying to close the server
The server should not now accepts new requests, it should be in "closing state"
server is closed!
因此,例如,当 chrome 对网站图标再执行 1 个请求时,服务器无法关闭。
现在我将继续使用 worker.kill(),这使得工作人员不必等待服务器停止。
关于javascript - Node.js 域集群工作器断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20382425/