Nodejs http.request奇怪的延迟

时间:2014-02-03 17:16:52

标签: javascript node.js express

我发现了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

2 个答案:

答案 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();