4

我在 Linux 机器(Ubuntu 12.04 64 位,3.75GB 内存,1 个核心)上有一个 express(node.js v0.10.29)代理,它为每个传入请求发出一些出站 HTTP 请求。在负载测试时,我发现响应时间变得非常慢(在触发 1000 时发出 4 个出站请求的请求大约需要 30 秒)。经过一番调查,我确定出站请求是瓶颈并消除了机器限制(cpu 和内存没有超过 20%,我将打开文件的数量增加到 10000)。首先,我对出站请求使用 request 模块,尝试将其更改为 http 模块,并为他们两个尝试增加globalAgent.maxSockets, using agent = false, using 我自己的代理和任意数量的maxSockets, setting request.setNoDelay(true), usingcluster,但我的负载测试结果没有任何改变。

可能是什么问题?

这是我最新的 HTTP 请求代码:

var http = require('http');
var agent = new http.Agent();
agent.maxSockets = 100;

var doPost = function(reqUrl, body, next, onError) {
    var stringBody = JSON.stringify(body);
    var headers = {
        'Content-Type': 'application/json',
        'Accept-Encoding': 'gzip',
        'Content-Length': stringBody.length
    };
    var parsedUrl = url.parse(reqUrl);
    var options = {
        host: parsedUrl.host,
        path: parsedUrl.path,
        method: 'POST',
        headers: headers,
        //agent: false
        agent: agent
    };

    doHttpRequest(options, stringBody, next, onError);
};


function doHttpRequest(options, body, next, onError, HttpContext){
    var req = http.request(options, function(res) {
         var chunks = [];
         res.on('data', function (chunk) {
            chunks.push(chunk);
         });

         res.on('end', function(){
            var buffer = Buffer.concat(chunks);
            var encoding = res.headers['content-encoding'];
            if (encoding == 'gzip') {
                zlib.gunzip(buffer, function(error, decoded) {
                    var jsonRes = JSON.parse(decoded && decoded.toString());
                    next(jsonRes);
                });
            } else if (encoding == 'deflate') {
                zlib.inflate(buffer, function(error, decoded) {
                    var jsonRes = JSON.parse(decoded && decoded.toString());
                    next(jsonRes);  
                });
            } else {
                next(null, buffer.toString());
            }
        });
    });

    req.setNoDelay(true);
    req.write(body);
    req.end();
    req.on('error', function(e) {
        log(e);
    });
}

“next”方法将调用“doPost”函数几次(在本例中为 4 次)。

4

1 回答 1

0

我看到了同样的行为,我创建了简单的代理模块。当我直接调用一个端点时,它需要 50 毫秒,但通过代理服务器(内部创建另一个请求并管道到原始请求)它需要两倍 ~ 100 毫秒。我也尝试了你在这里提到的所有选项。

我很高兴我不是唯一一个遇到这个问题的人,我会进一步研究。如果发现了什么,会通知你。

更新

在代理上设置keepAlive=true后,我能够以比直接调用多约 5 毫秒的速度获得代理请求的结果。

于 2015-03-20T03:16:06.283 回答