有没有办法在不重新启动的情况下更改Node.JS应用程序的代码。
例如,如果当时正在从服务器下载文件,是否有办法在不中断文件传输的情况下升级服务器?
答案 0 :(得分:8)
是的,可以使用cluster模块。
基本上,您将启动应用程序的多个从属实例,通过主进程共享同一端口。主设备将传入的连接分配给从设备。
当你想重新启动时,主人将按顺序:
这里有一些代码可以帮助您入门(您需要npm install async underscore
)。
注意:这只是为了让您入门。您应该准备好在真实设置中处理意外的从站故障和超时。
var cluster = require('cluster');
var http = require('http');
var _ = require('underscore');
var async = require('async');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log('starting master with PID', process.pid);
// Fork workers.
var slaves = {};
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('fork', function (worker) {
slaves[worker.id] = worker;
});
cluster.on('exit', function (worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
delete slaves[worker.id];
// restart the worker
cluster.fork();
});
process.on('SIGHUP', function restartApp() {
console.log('restarting all slaves');
// important: force node.js to reload all js sources
delete require.cache;
var toRestart = _(slaves).values();
async.eachSeries(toRestart, function (slave, done) {
slave.kill('SIGTERM');
// when the new worker starts, proceed to the next instance
cluster.once('listening', function () {
done();
});
});
});
} else {
console.log('- starting slave with PID', process.pid);
// Workers can share any TCP connection
// In this case its a HTTP server
var server = http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
});
process.on('SIGTERM', function () {
// finish all current connections, then stop
server.close(function () {
process.exit(0);
});
});
server.listen(8000);
}
当你调用`kill -HUP时,你会看到它按顺序重启所有从属:
worker 5156 died
- starting slave with PID 5164
worker 5157 died
- starting slave with PID 5165
worker 5158 died
- starting slave with PID 5166
worker 5159 died
- starting slave with PID 5167
重新启动时,总有3个正在运行的从站来处理传入连接。
最后一件事:如果您尝试,console.log
在从属SIGTERM处理程序中不执行任何操作,因为它已经与主服务器断开连接。