NoOps

Ops make no ops | Ops的目标是没有Ops,嗯!

Ruby Eventmachine The speed demon 【译】

作者: |   779 浏览  | 

原帖这里:http://www.igvita.com/2008/05/27/ruby-eventmachine-the-speed-demon/
由于译者能力有限,有错误或不足的地方还请见谅。

reactor是一种事件设计模式,并发处理提交给一个service handler的多个请求,当请求抵达后,service handler采用多路复用方式同步地分配这些请求至相关的request handlers。

为什么要从Reactor开始?
我们测试了很多不同的web-server架构,发现性能最好的总是采用事件驱动的服务。在一个并发处理成千上万请求的环境中,复制和上下文切换会导致产生更大的开销(fork的性能最差,它每次会在父进程上进行内存复制)。相比之下,一个紧密、高度优化的事件循环能够在高负载情况下表现出很好的性能。

EventMachine and Reactor pattern
近期听了很多ruby应用服务器替代方案的演讲,我得到了一个一致的意见:“事件驱动能够很好的处理轻量的请求,如果你有一个持续事件很长的请求,事件驱动将表现的非常差。”从技术上讲,有效,但在实践中,不一定是正确的。让我们先从一个最简单的例子开始:

这里我们使用eventmachine完成了一个最简单的http web-server。使用ab进行压力测试,并发5(-c 5),10个请求 ,结果处理时间用了20秒左右。和期望的一样,reactor同步方式处理每个请求,并发为1,10个请求,2秒处理一个 。

EventMachine: Reactor使用轻量并发?
在上个例子中,reactor 的同步性质造成了瓶颈,这也是EM脱离纯理论方式的地方。需要特别说明的,EM提供一种机制可以分配请求到一个线程池去处理(默认20个线程)。

测试一下,一共10个请求,并发为5,结果处理时间大约为4秒左右!说明我们的服务在并行处理请求,类似mongrel web-server。

Deferrable: 不使用线程的并发
Eventmachine从twisted(python事件驱动网络编程框架)借鉴很多,也提供一个deferrable模块,在某些情况下允许我们获得并发处理的优势,但没有任何线程开销! Deferrable允许你配置任意数量的Ruby代码块(callbacks或errbacks),当对应的Deferrable的对象状态在未来某个时刻发生改变时回调执行。想象一下你正在实现一个http server,但你需要远程调用一些其他的服务才能返回一个完整的客户请求。

没有线程,仍然可以在4秒左右完成40个请求的处理,唯一的限制是我们实现的上个例子,最多可以并发处理20个请求。这是eventmachine的美妙之处:如果你构造的work可以defer或阻塞在socket,reactor将循环继续处理其他的请求。当defer的工作完成后,它会产生一个成功的消息,reactor进行回调处理。没有使用线程,没有同步处理请求,Dnsruby是一个非常棒的例子,可以进一步学习这种模式

发表评论