Node.JS,Server close请求中间的Keep-Alive连接

时间:2015-04-21 22:44:46

标签: javascript node.js http pool keep-alive

我有Node.js HTTP服务器,如果它们空闲10秒钟关闭传入连接,而客户端使用Keep-Alive连接池来请求此服务器。当我以10秒的间隔开始发送请求时,我定期收到错误消息ECONNRESET,我认为因为连接在HTTP请求中间关闭。除了简单的重发请求之外,有没有优雅的解决方案?

server.js

var server = require('http').createServer(function(req, res) {
  console.log(new Date(), "Request ", req.method);
  res.end("Nice");
});

server.timeout = 10000;

server.on("connection", function(socket) {
  console.log("New connection");
  socket._created = new Date().getTime();
  socket.on("close", function() {
    var now = new Date().getTime();
    console.log(new Date(), "Socket closed, TTL", (now - socket._created)/1000);
  });
});
server.listen(3000);

client.js

var http = require("http");

var agent = new http.Agent({
  keepAlive: true
});

var reqSent = 0;
var NEED_REQS = 10;
var TIMEOUT = 10000;

function _req() {
  var start = new Date().getTime();
  var req = http.get({
    host: "localhost",
    port: 3000,
    agent: agent
  }, function(res) {
    reqSent++;
    var now = new Date().getTime();
    console.log("Sent:", reqSent, (now - start)/1000);

    if(reqSent >= NEED_REQS) {
      agent.destroy();
      return;
    }
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
    });

    setTimeout(function() {
      _req();
    }, TIMEOUT);
  });
  req.on("error", function(err) {
    console.error(err);
  });
}

_req();

正在运行client.js

$ node client.js
Sent: 1 0.028
Sent: 2 0.008
Sent: 3 0.002
{ [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' }

2 个答案:

答案 0 :(得分:2)

我确实每5秒发送一次请求就重现了您的问题。 nodejs中的默认keepAlive超时为5秒https://nodejs.org/api/http.html#http_server_keepalivetimeout

这个针对nodejs的github问题很好地解释了该行为,https://github.com/nodejs/node/issues/20256 解决方法是将keepAlive timout客户端设置为小于服务器端的超时,但是在nodejs https://nodejs.org/api/http.html#http_new_agent_options

中看不到这种选项

答案 1 :(得分:0)

我认为只有一个解决方案 - 如果获得ECONNRESET重发请求,我找到了包含这种逻辑的好lib https://github.com/FGRibreau/node-request-retry