【问题标题】:Can’t gracefully shut down a node + Express app (node http server's close function does not complete)无法正常关闭节点 + Express 应用(节点 http 服务器的关闭功能未完成)
【发布时间】: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函数可能无法完成吗?

【问题讨论】:

标签: node.js express


【解决方案1】:

.close() 实际上并没有关闭任何活动连接,它只会停止建立 连接,并且它会等待活动连接关闭(由客户端)。

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

有一个名为 http-shutdown 的包可以帮助优雅地关闭 HTTP 服务器。

【讨论】:

  • 谢谢!我通读了http-shutdown 的代码,它的方法似乎运行良好。不过,我仍然对 this piece of their code 的所作所为感到有些困惑。
  • @azangru 从它的外观来看,该模块跟踪所有传入连接(使其能够在调用关闭时关闭它们),并且您所指的代码基本上清除了已完成的连接(所以关闭时不会再次关闭,因为连接已经完成)。
猜你喜欢
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 2021-02-03
  • 2013-11-15
  • 2014-02-27
  • 2019-12-11
  • 2013-02-19
  • 1970-01-01
相关资源
最近更新 更多