Node.js Express 应用程序在负载测试下花费太多时间来处理出站 HTTP 请求
Posted
技术标签:
【中文标题】Node.js Express 应用程序在负载测试下花费太多时间来处理出站 HTTP 请求【英文标题】:Node.js Express application taking too much time to process outbound HTTP requests under load testing 【发布时间】:2014-09-29 13:55:46 【问题描述】:我在 Linux 机器(Ubuntu 12.04 64 位,3.75GB 内存,1 个核心)上有一个 express (node.js v0.10.29) 代理,它为每个传入请求发出一些出站 HTTP 请求。
在负载测试时,我发现响应时间变得非常慢(在触发 1000 时发出 4 个出站请求的请求大约需要 30 秒)。
经过一番调查,我确定出站请求是瓶颈并消除了机器限制(cpu 和内存没有超过 20%,我将打开文件的数量增加到 10000)。
首先,我将请求模块用于出站请求,尝试将其更改为 http 模块,并且他们都尝试增加globalAgent.maxSockets
,使用agent = false
,使用我自己的代理和任意数量的maxSockets
,设置@987654324 @,使用cluster
,但我的负载测试结果没有任何改变。
可能是什么问题?
这是我最新的 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 次)。
【问题讨论】:
【参考方案1】:我看到了同样的行为,我创建了简单的代理模块。当我直接调用端点时,它需要 50 毫秒,但通过代理服务器(内部生成另一个请求并管道到原始请求)它需要两倍 ~ 100 毫秒。我也尝试了您在此处提到的所有选项。
我很高兴不是我一个人遇到这个问题,我会进一步研究。如果发现了什么,会通知您。
更新
在代理上设置 keepAlive=true 后,我能够以比直接调用多约 5 毫秒的时间获得代理请求的结果。
【讨论】:
以上是关于Node.js Express 应用程序在负载测试下花费太多时间来处理出站 HTTP 请求的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 express 框架通过 node.js 获取远程客户端的本地 IP 地址?
Node JS+Express:如何在 HTML(EJS) 中定义和使用 MySQL 数据?