2

当所有连接都关闭时,此 Node.js 服务器将在 Ctrl+C 上完全关闭。

var http = require('http');
var app = http.createServer(function (req, res) {
  res.end('Hello');
});

process.on('SIGINT', function() {
  console.log('Closing...');
  app.close(function () {
    console.log('Closed.');
    process.exit();
  });
});

app.listen(3000);

这样做的问题是它包括keepalive连接。如果您在 Chrome 中打开此应用程序的选项卡,然后尝试 Ctrl+C 它,则当 Chrome 最终释放连接时,它不会关闭大约 2 分钟。

是否有一种干净的方法可以检测何时不再有 HTTP 请求,即使某些连接仍处于打开状态?

4

2 回答 2

2

finish您可以使用响应事件来破解一些请求跟踪:

var reqCount = 0;

var app = http.createServer(function (req, res) {
  reqCount++;
  res.on('finish', function() { reqCount--; });
  res.end('Hello');
});

允许您在关闭服务器时检查 reqCount 是否为零。

但是,正确的做法可能是不关心旧服务器,而只是启动一个新服务器。通常重新启动是为了获取新代码,因此您可以开始一个新进程而无需等待旧进程结束,可选择使用该child_process模块让一个顶级脚本管理整个事情。或者甚至使用该cluster模块,允许您在关闭旧进程之前启动新进程(因为cluster管理其子实例之间的流量平衡)。

我实际上还没有测试很远的一件事是,是否可以保证在server.close()返回后立即启动新服务器是安全的。如果没有,那么新服务器可能无法绑定。server.listen()文档中有一个关于如何处理此类EADDRINUSE错误的示例。

于 2013-03-05T16:52:52.493 回答
2

默认情况下没有套接字超时,这意味着连接将永远打开,直到客户端关闭它们。如果要设置超时,请使用此函数:socket.setTimeout

如果您尝试关闭服务器,您根本无法关闭,因为有活动连接,因此如果您尝试正常关闭,则关闭功能将挂起。唯一的方法是设置超时并在超时时终止应用程序。

如果你有工人,这并不像用 杀死应用程序那么简单process.exit(),所以我制作了一个完全符合你要求的模块:grace

于 2013-03-05T18:56:07.860 回答