我希望我正在处理的应用程序的基于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));
优美-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
打印出来控制台消息)。但是,如果我打开浏览器并实际访问localhost上的应用程序,以便服务器有一些工作要做,然后尝试关闭服务器,则server.close函数似乎没有完成(所以它永远不会使用process.exit
调用回调,直到最后setTimeout调用自己的回调并强制关闭应用程序。
server.close函数是来自节点lib的this function。
你能帮我弄清楚为什么节点服务器的close
功能可能无法完成吗?
答案 0 :(得分:1)
.close()
实际上并未关闭任何活动连接,它只会阻止新连接,并且它会等待活动连接关闭(由客户提供)。
如果连接的客户端保持连接打开(比如使用保持连接),则回调可能永远不会被调用。
有一个名为http-shutdown
的软件包可以帮助您正常关闭HTTP服务器。