使用Keepalive进行高效的HTTP关闭?

时间:2013-03-05 16:34:44

标签: node.js http

当所有连接都关闭时,此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请求,即使某些连接仍处于打开状态?

2 个答案:

答案 0 :(得分: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错误的示例。

答案 1 :(得分:2)

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

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

如果你有工作人员,那就不像使用process.exit()杀死应用程序那么简单,所以我制作了一个模块,可以极端地提出你所要求的内容:grace