【发布时间】:2017-03-04 22:13:09
【问题描述】:
我希望我正在开发的应用程序的基于 Express.js 的服务器在发送关闭信号(SIGTERM 或 SIGINT)时退出节点进程之前正确关闭所有连接。
我稍微修改了express-graceful-shutdown中间件(which is really simple),所以我的代码的相关部分大致如下:
server.js
import gracefulShutdown from './tools/graceful-shutdown';
const server = app.listen(config.port, () => {
console.log(`Server is running`);
});
app.use(gracefulShutdown(server));
graceful-shutdown.js:
function gracefulShutdownMiddleware(server) {
let shuttingDown = false;
const forceTimeout = 10 * 1000; // giving the app 10 seconds to shutdown gracefully
process.on('SIGTERM', gracefulExit); // listen for TERM signal (e.g. kill)
process.on ('SIGINT', gracefulExit); // listen for INT signal (e.g. Ctrl-C)
function gracefulExit() {
if (shuttingDown) return;
shuttingDown = true;
console.log('Received kill signal (SIGTERM), shutting down');
setTimeout(function () {
console.log('Could not close connections in time, forcefully shutting down');
process.exit(1);
}, forceTimeout);
server.close(function () {
console.log('Closed out remaining connections.');
process.exit();
});
}
function middleware(req, res, next) {
if (!shuttingDown) return next()
res.set('Connection', 'close')
res.status(503).send('Server is in the process of restarting.')
}
return middleware
}
export default gracefulShutdownMiddleware;
我观察到的问题是这样的。如果我在节点服务器启动后立即关闭它,它会按预期关闭(中间件中的函数gracefulExit 工作正常,server.close 执行良好,对server.close 的回调打印出控制台消息)。但是,如果我打开浏览器并实际访问本地主机上的应用程序,以便服务器有一些工作要做,然后尝试关闭服务器,则 server.close 函数似乎没有完成(所以它永远不会使用process.exit 调用回调,直到最后 setTimeout 调用自己的回调并强制关闭应用程序。
server.close 函数是来自节点库的this function。
你能帮我弄清楚为什么节点服务器的close函数可能无法完成吗?
【问题讨论】:
-
您遇到的问题与上述问题相同。也欢迎check out my answer there as well。