9

刚刚开始测试 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,我在有和没有 nginx 的服务器上使用 ab 进行了测试,得到了相反的结果。

还添加到 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 [#/sec](平均值)
    每个请求的时间:50.919 [ms](平均值)
    每个请求的时间:1.018 [ms](平均值,所有并发请求)
    传输速率:收到 159.18 [Kbytes/sec]

    连接时间(毫秒)
                  最小值平均值[+/-sd] 中值最大值
    连接: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 [#/sec](平均)
    每个请求的时间:80.463 [ms](平均)
    每个请求的时间:1.609 [ms](平均值,所有并发请求)
    传输速率:收到 113.48 [Kbytes/sec]

    连接时间(毫秒)
                  最小值平均值[+/-sd] 中值最大值
    连接: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 [#/sec](平均值)
    每个请求的时间:62.856 [ms](平均)
    每个请求的时间:1.257 [ms](平均值,所有并发请求)
    传输速率:收到 137.50 [Kbytes/sec]

    连接时间(毫秒)
                  最小值平均值[+/-sd] 中值最大值
    连接: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 [#/sec](平均)
    每个请求的时间:87.715 [ms](平均)
    每个请求的时间:1.754 [ms](平均值,所有并发请求)
    传输速率:收到 110.22 [Kbytes/sec]

    连接时间(毫秒)
                  最小值平均值[+/-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 测试旧版本一切正常。


4

2 回答 2

5

查看 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;
于 2012-07-04T22:05:03.557 回答
4

我已经为您提供了示例文件并使用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

笔记:

第二个例子和第一个例子一样快。小的差异可能是由于代码中的附加函数调用以及文档大小比第一个更大的事实造成的。

于 2012-07-04T21:26:17.750 回答