我发现了http.request函数的奇怪延迟。这是我的代码
var express = require('express');
var http = require('http');
app.set('port', process.env.PORT || 3000);
var app = express();
app.get('/aaa',function(req,res) {
setTimeout(function(){
res.json({"a":1});
},500);
});
app.get('/bbb',function(req,res){
var options = {
host: '127.0.0.1',
port: 3000,
path: '/aaa',
method: 'GET'
};
var request = http.request(options, function(result) {
result.on("data",function(){
});
res.json({"b":2});
});
request.on('error', function() {
res.json({"b":2});
});
request.end();
});
http.createServer(app).listen(app.get('port'), function(){
});
客户端调用/ bbb,然后是处理程序调用/ aaa,在500ms内结果返回给客户端。 我尝试使用Apache Bench测量不同情况下的响应时间:
1)1000个请求,包含1个并发请求
平均响应时间:500ms
2)包含50个并发请求的1000个请求
平均响应时间:5000ms
3)1000个并发请求的请求
平均响应时间:10000毫秒
为什么响应时间在增长?
我可以直接打电话给/ aaa
答案 0 :(得分:4)
这种行为并不罕见。回调到/ bbb(http.request
)中使用的HTTP客户端限制为每个主机5个并发套接字。换句话说,它只能并行生成5个HTTP请求。您可以找到对此here in the documentation
为了确认您达到了限制,您应该使用5和6个并发请求来运行测试。你会看到(正如我所做的)6个并发请求的平均响应时间显着下降。这是因为第6个并发请求将排队,直到完成对/aaa
的5个先前请求之一。
回答关于为什么响应时间增长的问题:您在基准测试中添加的并发性越多,平均响应时间就越长,因为每个请求必须等待队列中的更多请求完成才能获得套接字
您可以通过修改default agent来增加HTTP客户端可以处理的并发套接字数量:
var http = require("http");
http.globalAgent.maxSockets = 10;
您也可以将agent:false
传递给http.get
,完全绕过汇集:
http.get({hostname:'localhost', port:80, path:'/', agent:false}, function (res) {
// Do stuff
})
更新(2015年2月8日)
有关此答案的重要更改已在Node v 0.12.0中出现。
maxSockets不再限于5.默认设置现在设置为 Infinity与开发人员和操作系统给予控制 应用程序可以保持打开的同时连接数 给定的主持人。
答案 1 :(得分:0)
我有同样的问题,通过保持非常简单的解决方案来解决,如下所示
var req = http.get(requestUrl)
req.end();