Node.js比Apache慢

Art*_*Art 26 apache performance apache2 node.js

我正在比较Node.js(0.5.1-pre)和Apache(2.2.17)的性能,这是一个非常简单的场景 - 提供文本文件.

这是我用于节点服务器的代码:

var http = require('http')
  , fs = require('fs')

fs.readFile('/var/www/README.txt',
    function(err, data) {
        http.createServer(function(req, res) {
            res.writeHead(200, {'Content-Type': 'text/plain'})
            res.end(data)
        }).listen(8080, '127.0.0.1')
    }
)
Run Code Online (Sandbox Code Playgroud)

对于Apache,我只使用Ubuntu 11.04的默认配置

使用针对Apache的以下参数运行Apache Bench时

ab -n10000 -c100 http://127.0.0.1/README.txt
Run Code Online (Sandbox Code Playgroud)

我得到以下运行时:

Time taken for tests:   1.083 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      27630000 bytes
HTML transferred:       24830000 bytes
Requests per second:    9229.38 [#/sec] (mean)
Time per request:       10.835 [ms] (mean)
Time per request:       0.108 [ms] (mean, across all concurrent requests)
Transfer rate:          24903.11 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.8      0       9
Processing:     5   10   2.0     10      23
Waiting:        4   10   1.9     10      21
Total:          6   11   2.1     10      23

Percentage of the requests served within a certain time (ms)
  50%     10
  66%     11
  75%     11
  80%     11
  90%     14
  95%     15
  98%     18
  99%     19
 100%     23 (longest request)
Run Code Online (Sandbox Code Playgroud)

在针对节点实例运行Apache bench时,这些是运行时:

Time taken for tests:   1.712 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      25470000 bytes
HTML transferred:       24830000 bytes
Requests per second:    5840.83 [#/sec] (mean)
Time per request:       17.121 [ms] (mean)
Time per request:       0.171 [ms] (mean, across all concurrent requests)
Transfer rate:          14527.94 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.9      0       8
Processing:     0   17   8.8     16      53
Waiting:        0   17   8.6     16      48
Total:          1   17   8.7     17      53

Percentage of the requests served within a certain time (ms)
  50%     17
  66%     21
  75%     23
  80%     25
  90%     28
  95%     31
  98%     35
  99%     38
 100%     53 (longest request)
Run Code Online (Sandbox Code Playgroud)

这显然比Apache慢.如果您考虑到Apache正在执行许多其他操作(例如日志记录等),这一点尤其令人惊讶.

我做错了吗?或者在这种情况下Node.js真的慢了吗?

编辑1:我注意到节点的并发性更好 - 当将多个同时请求增加到1000时,Apache开始丢弃其中几个,而节点工作正常,没有连接丢失.

Alf*_*red 25

动态请求

node.js非常善于处理很多小动态请求(可以挂起/长轮询).但它不擅长处理大缓冲区.Ryan Dahl(作者node.js)解释了他的一个演讲.我建议你研究这些幻灯片.我也在网上看过这个.

垃圾收集器

正如你从幻灯片中看到的那样(13从45开始),大缓冲区很糟糕.

从45开始滑15:

V8有一代分类垃圾收集器.随机移动对象.Node无法获取指向要写入套接字的原始字符串数据的指针.

使用缓冲区

从45开始滑动16

使用Node的新Buffer对象,结果会发生变化.

仍然没有那么好,例如nginx,但好多了.这些幻灯片也很老了,所以Ryan甚至可以改进这个.

CDN

我仍然认为您不应该使用node.js来托管静态文件.您最好将它们托管在CDN上,该CDN针对托管静态文件进行了优化.一些流行的CDN(有些甚至免费)通过WIKI.

NGINX(+ Memcached的)

如果您不想使用CDN来托管您的静态文件,我建议您使用带有memcached的Nginx,这非常快.


And*_*rov 20

在这种情况下,Apache可能正在执行sendfile,导致内核将内存数据块(由fs驱动程序缓存)直接发送到套接字.在节点的情况下,有在V8中,libeio和内核之间的用户空间的数据复制一些开销(见在节点中使用的sendfile大文章)

在很多可能的情况下,节点将胜过Apache,例如"以尽可能多的tcp连接以尽可能多的速度发送数据流"