无法正常关闭节点+ Express应用程序(节点http服务器的关闭功能未完成)

时间:2016-10-22 19:44:44

标签: node.js express

我希望我正在处理的应用程序的基于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功能可能无法完成吗?

1 个答案:

答案 0 :(得分:1)

.close()实际上并未关闭任何活动连接,它只会阻止连接,并且它会等待活动连接关闭(由客户提供)。

如果连接的客户端保持连接打开(比如使用保持连接),则回调可能永远不会被调用。

有一个名为http-shutdown的软件包可以帮助您正常关闭HTTP服务器。