3

更新

这不应该是一个基准,或者节点与红宝石的事情(我应该在问题中更清楚地说明这一点,抱歉)。重点是比较和演示阻塞和非阻塞之间的区别以及编写非阻塞的难易程度。我可以比较一下使用 EventMachine 的例子,但是 node 有这个内置的,所以它是显而易见的选择。


我试图向一些朋友展示 nodejs(及其框架)相对于其他技术的优势,这种方式很容易理解,主要是非阻塞 IO 的事情。

所以我尝试创建一个(非常小的)Expressjs 应用程序和一个 Rails 应用程序,它会在 google 上执行 HTTP 请求并计算生成的 html 长度。

正如预期的那样(在我的电脑上)Expressjs 通过 ab 比 Rails 快 10 倍(见下文)。我的问题是,这是否是一种“有效”的方式来展示 nodejs 提供的优于其他技术的主要优势。(或者 Expressjs/Connect 中正在进行某种缓存?)

这是我使用的代码。

Expressjs

exports.index = function(req, res) {
    var http = require('http')
    var options = { host: 'www.google.com', port: 80, method: 'GET' }
    var html = ''
    var googleReq = http.request(options, function(googleRes) {
        googleRes.on('data', function(chunk) {
            html += chunk
        })
        googleRes.on('end', function() {
            res.render('index', { title: 'Express', html: html })
        })
    });
    googleReq.end();
};

导轨

require 'net/http'

class WelcomeController < ApplicationController
  def index
    @html = Net::HTTP.get(URI("http://www.google.com"))
    render layout: false
  end
end

这是 AB 基准测试结果

Expressjs

Server Software:        
Server Hostname:        localhost
Server Port:            3000

Document Path:          /
Document Length:        244 bytes

Concurrency Level:      20
Time taken for tests:   1.718 seconds
Complete requests:      50
Failed requests:        0
Write errors:           0
Total transferred:      25992 bytes
HTML transferred:       12200 bytes
Requests per second:    29.10 [#/sec] (mean)
Time per request:       687.315 [ms] (mean)
Time per request:       34.366 [ms] (mean, across all concurrent requests)
Transfer rate:          14.77 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       0
Processing:   319  581 110.6    598     799
Waiting:      319  581 110.6    598     799
Total:        319  581 110.6    598     799

Percentage of the requests served within a certain time (ms)
  50%    598
  66%    608
  75%    622
  80%    625
  90%    762
  95%    778
  98%    799
  99%    799
 100%    799 (longest request)

导轨

Server Software:        WEBrick/1.3.1
Server Hostname:        localhost
Server Port:            3001

Document Path:          /
Document Length:        65 bytes

Concurrency Level:      20
Time taken for tests:   17.615 seconds
Complete requests:      50
Failed requests:        0
Write errors:           0
Total transferred:      21850 bytes
HTML transferred:       3250 bytes
Requests per second:    2.84 [#/sec] (mean)
Time per request:       7046.166 [ms] (mean)
Time per request:       352.308 [ms] (mean, across all concurrent requests)
Transfer rate:          1.21 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0  180 387.8      0     999
Processing:   344 5161 2055.9   6380    7983
Waiting:      344 5160 2056.0   6380    7982
Total:        345 5341 2069.2   6386    7983

Percentage of the requests served within a certain time (ms)
  50%   6386
  66%   6399
  75%   6402
  80%   6408
  90%   7710
  95%   7766
  98%   7983
  99%   7983
 100%   7983 (longest request)
4

2 回答 2

5

为了补充肖恩的回答:

基准是无用的。他们展示了你想看到的东西。他们没有显示真实的图片。如果您的应用程序所做的只是对 google 的代理请求,那么事件服务器确实是一个不错的选择(node.js 或基于 EventMachine 的服务器)。但通常你想做的不止于此。这就是 Rails 更好的地方。满足所有可能需求的宝石,熟悉的顺序代码(与回调意大利面条相反),丰富的工具,我可以继续。

在选择一种技术而不是另一种技术时,请评估所有方面,而不仅仅是代理请求的速度(除非您再次构建代理服务器)。

于 2012-05-10T04:52:58.600 回答
1

您正在使用 Webrick 进行测试。结果是无效的,因为 Webrick 一次只能处理请求。你应该使用thin之类的东西,它建立在eventmachine之上,可以一次处理多个请求。您在所有并发请求中的每个请求时间、传输速率和连接时间将显着提高,从而做出这种改变。

您还应该记住,由于 Google 的网络延迟,每次运行之间的请求时间会有所不同。您应该多次查看这些数字以获得可以比较的平均值。

最后,您可能不会在基准测试中看到 Node 和 Rails 之间的巨大差异。

于 2012-05-10T04:41:09.550 回答