2011-04-29 53 views
2

的优势,这是我的测试情况下,我发现EM并不比一般的TCP服务器什么是EventMachine的

更快的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 
+0

Ruby代码通常缩进两个空格,而不是四个。 – 2011-05-01 23:11:47

回答

2

与线程相比简单,而不是速度。在这里寻找更多的见解:EventMachine: Fast and Scalable Event-Driven I/O Framework

适用于您的问题的引文:

很多人都写了一个事实,即事件驱动程序不是理论上比任何线程得更快,那就是真正。但在实践中,如果您想要获得极高的可伸缩性和性能,同时仍能确保最大的稳健性,我认为事件驱动模型更容易处理。我编写的程序必须运行数月或数年,而不会崩溃,泄漏内存或展示任何类型的表现,因此在实践中,事件驱动编程可以更好地工作。现在,这是事件驱动编程的问题:你必须写“向后”。线程模型将程序状态(效率低下)存储在运行时堆栈的局部变量中。在EM中你必须自己做,这对于习惯于线程的程序员来说是非常不直观的。这就是为什么我对光纤感兴趣的原因,因为它打开了编写程序员看起来像阻塞I/O的东西的可能性,但仍然是平坦的并且不使用线程。

+0

我同意你对简单与速度的评论,但是在几个层面上引用是错误的。最主要的是“线程化模型在运行时栈中的本地变量中存储程序状态(效率低下)。”每个线程都有一个预分配的堆栈,在其上存储变量不会产生任何内存分配,只是一个线程的堆栈指针移动。 服务器应用程序设计没有银弹解决方案。它更多的是关于对常用技术的理解和对正在使用的工作的正确使用。 – 2014-04-01 10:52:51

+0

经验教训。在本地编写和检查评论,然后粘贴,以避免愚蠢的语法错误;) – 2014-04-01 11:02:54

1

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

看看Ilya Grigorik的this demo rails app。他使用Apache Benchmark同时击中服务器,就好像您从多个访问者获取流量到您的站点一样。这是您从事件机器获得优势的地方。不是所有对数据库的调用都排在后面,它们是异步发送的,结果非常显着。如果你安装了演示中,你可以通过在database.yml中

的mysql2适配器(慢)取代em_mysql2适配器(快)同样地看出差别,如果你在一个循环中打EventMachine的,你是同步特性的限制循环本身(慢)。

0

有一件事 - 您应该在EM.run进入事件循环之前调用EM.epoll,而不是在它内部。

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