Скорость отклика nodejs и nginx

Просто начал тестировать nodejs и хотел получить некоторую помощь в понимании следующего поведения:

Пример № 1:

var http = require('http');
http.createServer(function(req, res){
    res.writeHeader(200, {'Content-Type': 'text/plain'});
    res.end('foo');
}).listen(1001, '0.0.0.0');

Пример № 2:

var http = require('http');
http.createServer(function(req, res){
    res.writeHeader(200, {'Content-Type': 'text/plain'});
    res.write('foo');
    res.end('bar');
}).listen(1001, '0.0.0.0');

При тестировании времени отклика в Chrome:

Пример № 1 - 6-10 мс
пример № 2 - 200-220 мс

Но, если протестировать оба примера через nginx proxy_pass

server{
    listen 1011;
    location / {
        proxy_pass http://127.0.0.1:1001;
    }
}

я получаю это:

пример №1 - 4-8мс
Пример № 2 - 4-8 мс

Я не эксперт ни по nodejs, ни по nginx, и спрашиваю, может ли кто-нибудь объяснить это?

nodejs - v.0.8.1
nginx - v.1.2.2

Обновить:

Благодаря Hippo я сделал тест с ab на моем сервере с и без nginx, и получил противоположные результаты.

также добавлен в конфиге nginx proxy_cache off

server{
    listen 1011;
    location / {
        proxy_pass http://127.0.0.1:1001;
        proxy_cache off;
    }
}

Пример № 1 прямой:

ab -n 1000 -c 50 http:// 127.0.0.1:1001/

    Серверное программное обеспечение:        
    Имя хоста сервера: 127.0.0.1
    Порт сервера: 1001

    Путь к документу:/
    Длина документа:        65 байт

    Уровень параллелизма:      50
    Время, затраченное на тесты: 1,018 секунды
    Выполнено запросов: 1000
    Сбой запросов: 0
    Ошибки записи: 0
    Всего передано:      166000 байт
    HTML передано:       65000 байт
    Запросов в секунду:    981,96 [#/ сек] (среднее значение)
    Время на запрос:      50,919 [мс] (среднее)
    Время на запрос: 1,018 [мс] (среднее значение для всех одновременных запросов)
    Скорость передачи:          159,18 [Кбайт / с] получено

    Время соединения (мс)
                  мин среднее [+/- сд] медиана макс
    Коннект: 0 0 0,6      0       3
    Обработка:     0   50  44,9     19     183
    Ожидание:        0   49  44,8     17     183
    Всего:          1   50  44,7     19     183

Пример # 1 nginx:

ab -n 1000 -c 50 http:// 127.0.0.1:1011/

    Серверное программное обеспечение:        nginx/1.2.2
    Имя хоста сервера: 127.0.0.1
    Порт сервера: 1011

    Путь к документу:/
    Длина документа:        65 байт

    Уровень параллелизма:      50
    Время, затраченное на тесты:   1.609 секунды
    Выполнено запросов: 1000
    Сбой запросов: 0
    Ошибки записи: 0
    Всего передано: 187000 байт
    HTML передано:       65000 байт
    Запросов в секунду:    621,40 [#/ сек] (среднее значение)
    Время на запрос: 80,463 [мс] (среднее)
    Время на запрос:       1.609 [мс] (среднее значение для всех одновременных запросов)
    Скорость передачи: получено 113,48 [Кбайт / с]

    Время соединения (мс)
                  мин среднее [+/- сд] медиана макс
    Коннект: 0 0 0,6      0       3
    Обработка:     2   77  44,9     96     288
    Ожидание:     2   77  44,8     96     288
    Итого:          3   78  44,7     96     288

Пример № 2 прямой:

ab -n 1000 -c 50 http:// 127.0.0.1:1001/

    Серверное программное обеспечение:        
    Имя хоста сервера: 127.0.0.1
    Порт сервера: 1001

    Путь к документу:/
    Длина документа:        76 байт

    Уровень параллелизма:      50
    Время, затраченное на тесты: 1,257 секунды.
    Выполнено запросов: 1000
    Сбой запросов: 0
    Ошибки записи: 0
    Всего передано: 177000 байт
    Передано HTML:       76000 байт
    Запросов в секунду:    795,47 [#/ сек] (среднее значение)
    Время на запрос: 62,856 [мс] (среднее)
    Время на запрос: 1,257 [мс] (среднее для всех одновременных запросов)
    Скорость передачи:          137.50 [Кбайт / с] получено

    Время соединения (мс)
                  мин среднее [+/- сд] медиана макс
    Коннект: 0 0 0,3      0       2
    Обработка:     0   60  47,8     88     193
    Ожидание:     0   60  47,8     87     193
    Итого:          0   61  47,7     88     193

Пример # 2 nginx:

ab -n 1000 -c 50 http:// 127.0.0.1:1011/

    Серверное программное обеспечение:        nginx/1.2.2 Имя хоста сервера: 127.0.0.1 Порт сервера: 1011 Путь к документу:/ Длина документа:        76 байт Уровень параллелизма:      50 Время, затраченное на тесты:   1.754 секунды Выполнение запросов: 1000 Сбой запросов: 0 Ошибки записи: 0 Всего передано:      198000 байт. Передано HTML:       76000 байт. Количество запросов в секунду:    570,03 [#/ сек] (среднее значение) Время на запрос: 87,715 [мс] (среднее значение) Время на запрос: 1,774 [мс] (среднее значение для всех одновременных запросов) Скорость передачи: 110,22 [кбайт / с] получено. Время соединения (мс) мин. Среднее значение [+/-sd] медиан макс. Соединение: 0 0 0,4      0       2 Обработка:     1   87  42,1     98     222 Ожидание:        1   86  42,3     98     222 Всего:     1   87  42,0 98 222


Теперь результаты выглядят более логично, но все равно есть странная задержка при звонке res.write()

Я думаю, это был (конечно, выглядит) глупый вопрос, но я все еще получаю огромную разницу во времени ответа в браузере с этой конфигурацией сервера (Centos 6) и этим конкретным сервером (vps).

На моем домашнем компьютере (Ubuntu 12), но при тестировании старых версий с localhost все работает нормально.


2 ответа

Решение

Просмотр http.js показывает, что у случая #1 есть особая обработка в самом nodejs, я полагаю, что это своего рода оптимизация быстрого доступа.

var hot = this._headerSent === false &&
            typeof(data) === 'string' &&
            data.length > 0 &&
            this.output.length === 0 &&
            this.connection &&
            this.connection.writable &&
            this.connection._httpMessage === this;

      if (hot) {
        // Hot path. They're doing
        //   res.writeHead();
        //   res.end(blah);
        // HACKY.

        if (this.chunkedEncoding) {
          var l = Buffer.byteLength(data, encoding).toString(16);
          ret = this.connection.write(this._header + l + CRLF +
                                      data + '\r\n0\r\n' +
                                      this._trailer + '\r\n', encoding);
        } else {
          ret = this.connection.write(this._header + data, encoding);
        }
        this._headerSent = true;

      } else if (data) {
        // Normal body write.
        ret = this.write(data, encoding);
      }

      if (!hot) {
        if (this.chunkedEncoding) {
          ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
        } else {
          // Force a flush, HACK.
          ret = this._send('');
        }
      }

      this.finished = true;

Я взял вам примеры файлов и использовал ab (Apache Benchmark) как подходящий инструмент для оценки производительности HTTP-сервера:

Пример 1:

Concurrency Level:      50
Time taken for tests:   0.221 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      104000 bytes
HTML transferred:       3000 bytes
Requests per second:    4525.50 [#/sec] (mean)
Time per request:       11.049 [ms] (mean)
Time per request:       0.221 [ms] (mean, across all concurrent requests)
Transfer rate:          459.62 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       4
Processing:     1   11   6.4     10      32
Waiting:        1   11   6.4     10      32
Total:          1   11   6.7     10      33

Пример 2:

Concurrency Level:      50
Time taken for tests:   0.256 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      107000 bytes
HTML transferred:       6000 bytes
Requests per second:    3905.27 [#/sec] (mean)
Time per request:       12.803 [ms] (mean)
Time per request:       0.256 [ms] (mean, across all concurrent requests)
Transfer rate:          408.07 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.6      0       4
Processing:     1   12   7.0     12      34
Waiting:        1   12   6.9     12      34
Total:          1   12   7.1     12      34

Замечания:

Второй пример так же быстр, как и первый. Небольшие различия, вероятно, вызваны дополнительным вызовом функции в коде и тем, что размер документа больше, чем у первого.

Другие вопросы по тегам