Node.JS,服务器在请求中间关闭 Keep-Alive 连接
Node.JS, Server close Keep-Alive connection in middle of request
我有 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' }
我认为只有一种解决方案 - 如果获得 ECONNRESET 则重新发送请求,我找到了很好的包含这种逻辑的库 https://github.com/FGRibreau/node-request-retry
我确实重现了您每 5 秒发送一次请求的问题。 nodejs默认的keepAlive超时时间是5秒,https://nodejs.org/api/http.html#http_server_keepalivetimeout
这个针对 nodejs 的 github 问题很好地解释了行为,https://github.com/nodejs/node/issues/20256
解决方法是将客户端的 keepAlive 超时设置为小于服务器端超时的值,但我在 nodejs 中看不到这样的选项,https://nodejs.org/api/http.html#http_new_agent_options
我有 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' }
我认为只有一种解决方案 - 如果获得 ECONNRESET 则重新发送请求,我找到了很好的包含这种逻辑的库 https://github.com/FGRibreau/node-request-retry
我确实重现了您每 5 秒发送一次请求的问题。 nodejs默认的keepAlive超时时间是5秒,https://nodejs.org/api/http.html#http_server_keepalivetimeout
这个针对 nodejs 的 github 问题很好地解释了行为,https://github.com/nodejs/node/issues/20256 解决方法是将客户端的 keepAlive 超时设置为小于服务器端超时的值,但我在 nodejs 中看不到这样的选项,https://nodejs.org/api/http.html#http_new_agent_options