升级Node.JS Web应用程序而不重新启动
有没有办法更改Node.JS应用程序的代码,而无需重新启动它。
例如,如果当时正在从服务器上下载文件,是否有办法升级服务器而不中断文件传输?
是的, 集群模块是可能的。
基本上,你将通过一个主进程启动你的应用程序共享相同端口的多个从实例。 主站将传入的连接分配给从站。
当你想重新启动时,主人将按顺序:
- 停止传递连接到一个奴隶
- 轻轻地告诉它重新启动
- 等待它重生
这里有一些代码让你开始(你需要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
在slave SIGTERM处理程序中不做任何事情,因为它已经与master断开连接。