2

这是我的测试用例,我发现EM并不比一般的TCP服务器快

EM 服务器:

    require 'rubygems'
    require 'benchmark'
    require 'eventmachine'
    class Handler  < EventMachine::Connection
      def receive_data(data)
            operation = proc do
                # simulate a long running request
                 a = []
                n = 5000
                for i in 1..n
                    a << rand(n)
                    a.sort!
                end
            end

        # Callback block to execute once the request is fulfilled
        callback = proc do |res|
            send_data "send_response\n"
        end

            puts data
            EM.defer(operation, callback)
      end
    end

    EventMachine::run {
      EventMachine.epoll
      EventMachine::start_server("0.0.0.0", 8080, Handler)
      puts "Listening..."
    }

和我的基准测试:

require 'rubygems'
require 'benchmark'
require 'socket'
Benchmark.bm do |x|
    x.report("times:") do
        for i in 1..20
            TCPSocket.open "127.0.0.1", 8080 do |s|
                    s.send "#{i}th sending\n", 0    
                if line = s.gets
                    puts line
                end
                puts "#{i}th sending"
            end
        end
    end
end
4

3 回答 3

3

与线程相比简单,而不是速度。在这里查看更多见解:EventMachine:快速且可扩展的事件驱动 I/O 框架

适用于您的问题的引文:

关于事件驱动程序在理论上并不比线程程序快的事实已经写了很多,这是真的。但在实践中,我认为事件驱动模型更易于使用,如果您想获得极高的可扩展性和性能,同时仍确保最大的稳健性。我编写的程序必须运行数月或数年而不会崩溃、内存泄漏或表现出任何不稳定的性能,因此在实践中,事件驱动的编程效果更好。现在,这是事件驱动编程的问题:您必须“向后”编写。线程模型将您的程序状态(低效)存储在运行时堆栈上的局部变量中。在 EM 中你必须自己做,这对于习惯于线程的程序员来说是非常不直观的。这就是我对纤维感兴趣的原因

于 2011-04-29T13:14:57.397 回答
1

我们昨天刚刚在我们的项目中完成了这个练习。概念上的障碍比比皆是。

看看Ilya Grigorik的这个演示 rails 应用程序。他使用 Apache Benchmark 同时访问服务器,就好像您从多个访问者那里获得了访问您网站的流量一样。这是您从 eventmachine 获得优势的地方。不是将所有对数据库的调用都排在后面,而是异步发送,结果非常引人注目。如果您安装演示,您可以通过将 em_mysql2 适配器(快速)替换为 database.yml 中的 mysql2 适配器(慢)来查看差异

同样,如果您在循环中点击 eventmachine,您会受到循环本身的同步性质的限制(慢)。

于 2011-04-29T15:57:42.480 回答
0

一件事-您应该在使用 EM.run 而不是在其中进入事件循环之前调用 EM.epoll。

EventMachine.epoll
EventMachine::run {
  EventMachine::start_server("0.0.0.0", 8080, Handler)
  puts "Listening..."
}
于 2014-03-13T02:32:29.927 回答