Nodejs http.request奇怪的延迟

我发现了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,并在500毫秒结果返回到客户端。 我试图用Apache Bench来测量不同情况下的响应时间:

1)具有1个并发请求的1000个请求。
平均响应时间:500ms
2)具有50个并发请求的1000个请求。
平均响应时间:5000ms
3)有100个并发请求的1000个请求。
平均响应时间:10000ms

为什么响应时间越来越长?

当我直接调用/ aaa时没关系

这不是不寻常的行为。 用于callback/ bbb( http.request )的HTTP客户端限于每个主机5个并发套接字。 换句话说,它只能并行5个HTTP请求。 您可以在文档中find对此的参考

为了确认您达到了极限,您应该使用5个和6个并发请求运行testing。 你会看到(和我一样)平均响应时间显着下降6个并发请求。 这是因为第6个并发请求将排队,直到/aaa的5个前面的请求之一完成。

要回答你为什么响应时间增长的问题:你在基准testing中添加的并发性越多,平均响应时间就越长,因为每个请求必须等待队列中的更多请求才能获得套接字。

您可以通过修改默认代理来增加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,开发人员和操作系统可以控制应用程序可以保持与给定主机打开的同时连接数。