Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs response speed and nginx

Tags:

node.js

nginx

Just started testing nodejs, and wanted to get some help in understanding following behavior:

Example #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');

Example #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');

When testing response time in Chrome:

example #1 - 6-10ms
example #2 - 200-220ms

But, if test both examples through nginx proxy_pass

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

i get this:

example #1 - 4-8ms
example #2 - 4-8ms

I am not an expert on either nodejs or nginx, and asking if someone can explain this?

nodejs - v.0.8.1
nginx - v.1.2.2

update:

thanks to Hippo, i made test with ab on my server with and without nginx, and got opposite results.

also added to nginx config proxy_cache off

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

example #1 direct:

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


    Server Software:        
    Server Hostname:        127.0.0.1
    Server Port:            1001

    Document Path:          /
    Document Length:        65 bytes

    Concurrency Level:      50
    Time taken for tests:   1.018 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      166000 bytes
    HTML transferred:       65000 bytes
    Requests per second:    981.96 [#/sec] (mean)
    Time per request:       50.919 [ms] (mean)
    Time per request:       1.018 [ms] (mean, across all concurrent requests)
    Transfer rate:          159.18 [Kbytes/sec] received

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.6      0       3
    Processing:     0   50  44.9     19     183
    Waiting:        0   49  44.8     17     183
    Total:          1   50  44.7     19     183

example #1 nginx:

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


    Server Software:        nginx/1.2.2
    Server Hostname:        127.0.0.1
    Server Port:            1011

    Document Path:          /
    Document Length:        65 bytes

    Concurrency Level:      50
    Time taken for tests:   1.609 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      187000 bytes
    HTML transferred:       65000 bytes
    Requests per second:    621.40 [#/sec] (mean)
    Time per request:       80.463 [ms] (mean)
    Time per request:       1.609 [ms] (mean, across all concurrent requests)
    Transfer rate:          113.48 [Kbytes/sec] received

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.6      0       3
    Processing:     2   77  44.9     96     288
    Waiting:        2   77  44.8     96     288
    Total:          3   78  44.7     96     288

example #2 direct:

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


    Server Software:        
    Server Hostname:        127.0.0.1
    Server Port:            1001

    Document Path:          /
    Document Length:        76 bytes

    Concurrency Level:      50
    Time taken for tests:   1.257 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      177000 bytes
    HTML transferred:       76000 bytes
    Requests per second:    795.47 [#/sec] (mean)
    Time per request:       62.856 [ms] (mean)
    Time per request:       1.257 [ms] (mean, across all concurrent requests)
    Transfer rate:          137.50 [Kbytes/sec] received

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.3      0       2
    Processing:     0   60  47.8     88     193
    Waiting:        0   60  47.8     87     193
    Total:          0   61  47.7     88     193

example #2 nginx:

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


    Server Software:        nginx/1.2.2
    Server Hostname:        127.0.0.1
    Server Port:            1011

    Document Path:          /
    Document Length:        76 bytes

    Concurrency Level:      50
    Time taken for tests:   1.754 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      198000 bytes
    HTML transferred:       76000 bytes
    Requests per second:    570.03 [#/sec] (mean)
    Time per request:       87.715 [ms] (mean)
    Time per request:       1.754 [ms] (mean, across all concurrent requests)
    Transfer rate:          110.22 [Kbytes/sec] received

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.4      0       2
    Processing:     1   87  42.1     98     222
    Waiting:        1   86  42.3     98     222
    Total:          1   87  42.0     98     222


Now results looks more logic, but still there is a strange delay when calling res.write()

I guess it was (sure looks like) a stupid question, but i still get huge difference in response time in browser with this server configuration (Centos 6) and this concrete server (vps).

On my home computer (Ubuntu 12) but with older versions testing from localhost everything works fine.


like image 762
alxone Avatar asked Jul 04 '12 21:07

alxone


2 Answers

Peeking into http.js reveals that case #1 has special handling in nodejs itself, some kind of a shortcut optimization I guess.

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;
like image 125
Peter Aron Zentai Avatar answered Oct 04 '22 12:10

Peter Aron Zentai


I've took you examples files and used ab (Apache Benchmark) as a proper tool for benchmarking HTTP server performance:

Example 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

Example 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

Note:

The second example is as fast as the first one. The small differences are probably caused by the the additional function call in the code and the fact that the document size is larger then with the first one.

like image 34
TheHippo Avatar answered Oct 04 '22 12:10

TheHippo