У меня проблема с производительностью с помощью http-модуля Node.js.Node.js HTTP-ответная локальная производительность
Я пишу небольшой скрипт узла, чтобы сделать веб-сервер, который отправляет данные на указанную продолжительность (в секундах). Цель состоит в том, чтобы проводить тесты скорости между клиентами и сервером. И местные тесты скорости тоже. Для этого я использую пользовательский Readable, который я 'pipe' для ответа http. Этот пользовательский Readable прекращает отправку данных по истечении заданной продолжительности. Данные представляют собой циклический буфер произвольных значений.
Код выглядит так:
var http = require("http");
var Readable = require('stream').Readable;
var url = require('url');
var buff = new Buffer(16384); // change this to bigger value for better local performances
buff.fill(0); // data is filled with 0s here, change to whatever
// this function creates a Readable that will provide data for <duration> seconds and then will nd.
function createTimedReadable(duration)
{
var EndAt = Date.now() + 1000*duration; // when to end
var rs = new Readable();
rs.EndAt = EndAt;
rs._read = function() {
if (Date.now() < rs.EndAt)
rs.push(buff);
else
rs.push(null);
}
return(rs);
}
// each client request will call this function
function onHTTPrequest(request, response) {
var who = request.connection.remoteAddress + ":" + request.connection.remotePort;
console.log("Request received from " + who);
var duration = 10; // (actually we get it from the url query part)
// send the header: it's unknown size of binary data
response.writeHead(200,
{
'Content-Type' : 'octet-stream',
'Cache-Control' : 'no-cache, no-transform'
});
// link (pipe) the Readable to the response
var timedReadable = createTimedReadable(duration);
timedReadable.pipe(response);
}
// main - start the server
http.createServer(onHTTPrequest).listen(8888);
console.log("Server has started");
Для вызова сервера в течение 10 секунд:
wget -O /dev/null http://serverip:8888
Данные отбрасывается на стороне клиента (/ DEV/нуль), потому что мы не делаем хотите, чтобы запись на диске замедляла работу и возилась с результатами теста скорости.
При проведении тестов «по проводам» (2 машины) скорость кажется прекрасной, но при выполнении локального теста (одна и та же машина на том же компьютере) скорость неправильная, очень медленная и очень зависящая от размера переменной Buffer (положительный эффект). Использование очень большого размера для этого буфера дает лучшую производительность. Например, на одной и той же тестовой машине:
with a 16k buffer, we get 188 MB/s
with a 128k buffer, we get 487 MB/s
with a 1M buffer, we get 558 MB/s
with a reference code written in C using a 4K buffer, we get 626 MB/s
«по проводам» мы не видим эту проблему, потому что мы используем GigaEthernet (Ge), поэтому мы не можем идти быстрее, чем ~ 110MB/с, но с более быстрыми проводами (например, 10Ge) мы были бы ограничены 188 МБ/с с 16-килобайтным буфером. Если мы используем 4K-буфер, такой как код C, чем код узла, он даже не достигает скорости Ge, мы получаем только 69 МБ/с.
Так что есть ограничение где-то, я не знаю, где. И я не понимаю, почему размер буфера влияет на производительность, так как мы используем цикл Readable. Bascially, почему вызов «push» 8 раз с 16k данными каждый раз медленнее, чем вызов его 1 раз с данными 128k (16k * 8).
ИЛИ Может ли быть другой способ сделать эффективные «ограниченные по времени потоки»?
Спасибо.