Nodejs 实测http.request的keep-alive无效
Nodejs 实测http.request的keep-alive无效
利用http.Agent保持http连接,以便重用,但是实测每次都重新建立新连接,代码如下:
var http = require('http');
var agent = new http.Agent();
agent.maxSockets = 2;//设置最大两个连接
var options = {
hostname: 'www.baidu.com',
path: '/img/bd_logo1.png',
agent: agent,
headers: {'Connection': 'keep-alive'}
};
function reqBaidu(){
var req = http.get(options, function(res) {
console.log("Got response: " + res.statusCode);
});
}
reqBaidu();//运行结果:Got response: 200
setTimeout(reqBaidu, 100);//运行结果:Got response: 200
setTimeout(reqBaidu, 4000);//运行结果:等了很久(60多秒)才出结果Got response: 200,难道连接池中的两个socket被占用了?
使用Microsoft Network Monitor 3.4查看tcp连接情况如下,三次http请求都使用了新的socket,这是为什么呢,或许是我分析错了,还请指正。
4 回复
Node.js 实测 http.request
的 Keep-Alive 无效
背景
在使用 Node.js 的 http.request
方法时,我们希望重用 HTTP 连接以提高性能。为了实现这一点,我们可以使用 http.Agent
来管理连接池。然而,在实际测试中发现,每次请求似乎都会重新建立新的连接,而不是重用已有的连接。
示例代码
var http = require('http');
// 创建一个 Agent 对象,并设置最大连接数为 2
var agent = new http.Agent({
maxSockets: 2,
keepAlive: true,
keepAliveMsecs: 1000
});
var options = {
hostname: 'www.baidu.com',
path: '/img/bd_logo1.png',
agent: agent,
headers: {'Connection': 'keep-alive'}
};
function reqBaidu() {
var req = http.get(options, function(res) {
console.log("Got response: " + res.statusCode);
});
// 请求错误处理
req.on('error', function(e) {
console.error(`Got error: ${e.message}`);
});
}
// 运行三次请求,间隔时间分别为 0ms 和 4s
reqBaidu(); // 运行结果:Got response: 200
setTimeout(reqBaidu, 100); // 运行结果:Got response: 200
setTimeout(reqBaidu, 4000); // 运行结果:等了很久(60多秒)才出结果 Got response: 200,难道连接池中的两个 socket 被占用了?
分析与解决
从上述代码和运行结果来看,我们期望通过 http.Agent
重用连接,但实际上每次请求都创建了一个新的连接。这可能是由于以下几个原因:
- 服务器端的限制:服务器可能配置了某些限制,导致它不支持或不响应
keep-alive
请求。 - 超时问题:如果连接在一段时间内没有活动,可能会被关闭。可以通过设置
keepAliveMsecs
来延长空闲连接的存活时间。 - 连接池限制:虽然设置了
maxSockets
为 2,但有可能在这段时间内连接池中的两个 socket 都被占用。
解决方案
为了验证和解决问题,可以尝试以下步骤:
- 增加日志输出:添加更多的日志输出,以了解连接的状态。
- 检查服务器配置:确保服务器支持
keep-alive
。 - 调整超时设置:增加
keepAliveMsecs
时间,延长空闲连接的存活时间。
var agent = new http.Agent({
maxSockets: 2,
keepAlive: true,
keepAliveMsecs: 5000 // 延长空闲连接的存活时间
});
通过以上步骤,应该能够更好地理解并解决 http.request
中 keep-alive
失效的问题。
0.10 的 http agent 需要有请求排队的情况才会出现keepalive,如果没有排队请求,会马上断开socket连接。