У меня есть экспресс-прокси (node.js v0.10.29) на Linux-машине (Ubuntu 12.04, 64 бит, 3,75 ГБ памяти, 1 ядро), который делает несколько исходящих HTTP-запросов для каждого входящего запроса. Во время нагрузочного тестирования я обнаружил, что время отклика становится очень медленным (около 30 секунд для запроса, который делает 4 исходящих запроса при запуске 1000). После некоторого исследования я убедился, что исходящие запросы являются узким местом, и устранил машинное ограничение (процессор и память не превышают 20%, и я увеличил количество открытых файлов до 10000). Сначала я использовал модуль запроса для исходящего запроса, попытался изменить его на модуль http, и для обоих из них попытался увеличить globalAgent.maxSockets
, используя agent = false
, используя свой собственный агент с любым количеством maxSockets
, установив request.setNoDelay(true)
, используя 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);
});
}
метод «следующий» вызовет функцию «doPost» несколько раз (в данном случае 4 раза).