写点什么

EventMachine:高速可伸缩的事件驱动 I/O 框架

  • 2008-08-02
  • 本文字数:3083 字

    阅读完需:约 10 分钟

EventMachine 是一个基于 Reactor 设计模式的、用于网络编程和并发编程的框架。Reactor 模式描述了一种服务处理器,它接受事件并将其分发给已注册的事件处理。这种模式的好处就是清晰的分离了时间分发和处理事件的应用程序逻辑,而不需引入多线程来把代码复杂化。

EventMachine 提供了一个网络套接字和隐藏底层操作的高层接口。 EventMachine 的目标是

  • 拥有极高的可伸缩性、性能和稳定性,适用于大多数苛刻的生产环境;并且
  • 提供可以消除高性能多线程网络编程的复杂性的 API,使得工程师可以专心于产品逻辑本身

来看一个小例子,一个简单的聊天服务器:

<pre id="dyge20"> require 'eventmachine'<p> module Chat</p><br id="dyge23"></br> <br id="dyge24"></br> # Called after the connection with a client has been established<br id="dyge25"></br>  def post_init <br id="dyge26"></br> # Add ourselves to the list of clients<br id="dyge27"></br>   (@@connections ||= []) << self <br id="dyge28"></br> send_data "Please enter your name: "<br id="dyge29"></br>  end <p>  # Called on new incoming data from the client</p><br id="dyge32"></br>  def receive_data data<br id="dyge33"></br>  # The first message from the user is its name<br id="dyge34"></br>  @name ||= data.strip<br id="dyge35"></br> <br id="dyge36"></br> @@connections.each do |client|<br id="dyge37"></br>   # Send the message from the client to all other clients<br id="dyge38"></br>  client.send_data "#{@name} says: #{data}"<br id="dyge39"></br>  end<br id="dyge40"></br>  end<br id="dyge41"></br> end<p> # Start a server on localhost, using port 8081 and hosting our Chat application</p><br id="dyge44"></br> EventMachine::run do<br id="dyge45"></br>  EventMachine::start_server "localhost", 8081, Chat<br id="dyge46"></br> end我们采访了 EventMachine(EM)的主要开发人员 Francis Cianfrocca。我们询问了他开发 EventMachine 的动机是什么:

最初我启动这个项目是因为我打算写一个高性能的、面向消息的中间件,以便可以在脚本语言(包括 Ruby)下面开发起来更方便。如今已经有很多很多基于 EM 的项目了,但是那个中间件项目却还没搞定呢!我试图寻找一种方法来创建高度可伸缩的、适用于访问策略执行解决方案。并且我还需要一个足够高速的通信框架,而且还内建安全保障。

EventMachine 使用了 Thin (高速而简单 Ruby Web 服务器) Swiftiply (用于网络应用的集群化代理服务器)、 Evented Mongrel (网络流量由 EventMachine 处理的 Mongrel)、 Sparrow (基于 memcache 的轻量级的队列)和 Juggernaut (Ruby on Rails 的插件,服务器可以初始一个连接并将数据推送给客户端)。Francis 同时也编写了自己的 Web 框架:

我的框架叫做 Unicycle,它主要为 REST 化的应用而设计,就是那些对于那些需要通过 Web 请求和其他应用进行交互的网络应用。它也是基于 EM 的,使用的是 EM 内建的 HTTP 服务器。

EventMachine 的 0.12 版最近刚刚发布了:

在 0.12 版中我们作了一些性能的提升并引入了一些小特性,但最主要的是,我们发布了一个二进制的 gem,而它包括了自 0.8 版以来的所有特性。

EventMachine 的核心是 Reactor,最初是由 C++ 实现的,并可以被除了 Ruby 以外的其他语言使用。而且也有一个纯 Ruby 的实现,在下个版本中还有一个 Java 的实现,是用 JRuby 编写的:

待 发布的新特性中最重要的就是对 JRuby 的全面支持。想要这样就要用 Java 完全重写 reactor 核心。其实不但做到了,而且做得不错。Charles Nutter 和他的团队在 JRuby 上硕果累累,而且我认为还有巨大的潜力。我同时对 Rubinius 也颇感兴趣。Rubinius 的有趣之处在于其对纤 程(Fibers)的支持,这会使得 EM 的编程风格更加自然。我已经试用了 Ruby 1.9,但是我在更多的人使用新平台之前还没想好要不要升级 API。EM 的关键设计目标之一便是要保持最大的兼容性。

我们请 Francis 详细的谈谈 EventMachine 的优势:

从 技术上说,使用 EM 的重要原因就是,它引入了一种避免使用线程的编程模型。线程化编程当然早就被大家所熟知,尤其是在网络服务器方面,但是它也存在很多顽 疾。有一类问题是很适合用线程化模型来解决的,网络服务器就是其中之一。因为它通常需要为每个请求创建一个不相交的工作集。但是如果在线程之间有共享状态 的话,那么要让多线程程序 100% 正确运行是相当困难的,又或者它依赖于跨线程的操作顺序的正确性。在 Ruby 中,这种线程化所导致的问题是非常严重的。另外一个使用 EM 的理由就是,我们广泛地支持各种网络协议。我们的目标就是可以提供给开发者们一个庞大、成熟而又高性能的工具集合,可以让他们轻松地在自己的应用中使用。这也是为什么 EM 与其他很多工程的不同之处,它们仅仅是试图去简单地实现一个 reactor 模型而已。

我们也谈到了为什么相比较线程模型而言,事件驱动编程更加易用:

有 种说法是,从理论上说事件驱动编程并不比线程化编程快到哪里去,这是没错。但是在实践当中,我认为如果你想在保持最大可靠性的情况下能够获得最高的可扩展 性和性能的化,事件驱动模型更容易做到。我写的程序可以几个月甚至几年运行正常,没有崩溃,没有内存泄露,没有存在任何性能问题。因此在实践当中,事件驱 动编程更棒。现在,对于事件驱动编程来说还有个问题:那就是你需要“退步地”去编写程序。在线程模型中,程序状态被存在运行时的一个栈的本地变量中(尽管 很低效)。而在 EM 中,你需要自己去做这件事,这对于习惯于线程的程序员来说就很不直观。这也是为什么我对纤程(Fibers)感兴趣的原因,因为它可以 让程序看上去很像是那些喜欢 I/O 阻塞的程序员们写出来的。

更具体一些,拿 HTTP 服务器举例:

试 想一个使用线程的 HTTP 服务器,你只需简单地读取套接字然后阻塞,直到数据从另一端传输过来。如果使用事件的话,你就省去了等待或者调度上的开销,数据 一来你就收到了──但是数据可能是不完整的!在程序中你需要判断对于这个请求你是否收到了完整的数据,如果不是的话你就要存贮中间数据。但是你的程序处理 的下一个事件可能就是另一个连接传来的数据,所以你需要把这些都存下来。线程化抽象使用了一种很重量级的方式来保证工作集独立,因此按理说它也更为直观一 些。但是事件化模型也并不是十分难学。不过,我依然认为这是推广事件驱动编程的最大壁垒。

幸运地是,这正是 EventMachine 的专长:

目 前 EM 做到的一点就是,将基本协议包装起来,将所有这些从程序员面前最大化地隐藏起来。不像那些仅仅提供了一个 reactor 核心的底层库(比如 libev),EM 希望可以提供所有标准网络协议的鲁棒实现,比如 Email 等等。EM 包含了一个精心编写的处理器,SMTP 的客户端和服务器端都支持。 因此 EM 的程序员仅需要为完成 Email 消息相关事件编写代码即可,并不需要接触到底层协议。但是你还可以享用到事件模型的其他优点,比如高速度和高伸缩 性等等。

你可以在 Rubyforge 的官方站点或者 rubyeventmachine.com 上找到更多关于 EventMachine 的信息:

我们最近刚刚开通了社区网站 rubyeventmachine.com , 这是个 Trac 系统,由 Jason Roelofs 搭建。还有 EventMachine 的 IRC 频道。包括 Kirk Haines、James Tucker(raggi)和 Aman Gupta(tmm1)在内的很多人都对 EM 贡献甚多。Thin 的贡献者 Marc-André Cournoyer 也提供了很多想法。

查看英文原文: EventMachine: Fast and Scalable Event-Driven I/O Framework

2008-08-02 22:527594
用户头像

发布了 80 篇内容, 共 21.8 次阅读, 收获喜欢 5 次。

关注

评论

发布
暂无评论
发现更多内容

作为Java程序员应该怎样去规划自己的学习路线,Java面试知识点

Java 程序员 后端

你还搞不定分布式系统流控、熔断吗,2021年最新Java面试点梳理

Java 程序员 后端

全套教程百度云,java菜鸟教程多态,Mybatis源码解析

Java 程序员 后端

关于Java性能优化的几点建议,图灵学院4期百度网盘,附项目源码

Java 程序员 后端

作为一名Java面试者你应该知道的,阿里,快手,拼多多等7家大厂Java面试真题

Java 程序员 后端

作为一名程序员我不忘初心,2021年是做Java开发人员的绝佳时机

Java 程序员 后端

作为一名程序员我不忘初心,听说你在找SpringBoot整合案例

Java 程序员 后端

作为程序员一定不要仅仅追求物质,Javaweb面试宝典

Java 程序员 后端

你不知道这份超详细JVM内存结构,Java吊打面试官系列

Java 程序员 后端

做Java程序员真的没有春天吗,12年高级工程师的“飞升之路”

Java 程序员 后端

全靠我啃烂了这份2021最新面试题,系统盘点Java开发者必须掌握的知识点

Java 程序员 后端

作为Java程序员,java尚学堂和尚硅谷,看完我工资从12K变成了20K

Java 程序员 后端

你想学的都在这里,开课吧java架构师百度云,阿里Java开发面试解答

Java 程序员 后端

入职3个月的Java程序员面临转正,原来SqlSession只是个甩手掌柜

Java 程序员 后端

全栈系统化的学习路线,基于SpringCloud微服务化开发平台项目

Java 程序员 后端

作为Java程序员应该怎样去规划自己的学习路线,2021Java者真的太难了

Java 程序员 后端

保持稳定迭代的秘密:基于Spinnaker的全自动渐进式交付

博文视点Broadview

你头秃都没想到还能这样吧,Java这些高端技术只有你还不知道

Java 程序员 后端

架构实战营-模块一

Aha hello xzy

架构实战营 「架构实战营」

关于Java性能优化的几点建议,java编程书籍合集百度云,终局之战

Java 程序员 后端

你不知道这份超详细JVM内存结构,京东校招Java面试题

Java 程序员 后端

作为一名Java面试者你应该知道的,Java多进程从头讲到尾

Java 程序员 后端

作为字节跳动面试官,linux菜鸟教程pdf下载,深度集成!

Java 程序员 后端

你连基础的JVM运行时内存布局都忘了,springmvc实战教程

Java 程序员 后端

作为一名程序员我不忘初心,java学习路线尚硅谷,Java工程师进阶之路

Java 程序员 后端

你有过迷茫吗,java的网络编程教程视频,这些知识点你会吗

Java 程序员 后端

关于SQL书写建议-&索引优化的总结,真香警告

Java 程序员 后端

作为一个码农终于把MySQL日记看懂了,中软国际Java笔试题和答案

Java 程序员 后端

你的技术真的到天花板了吗,值得推荐!

Java 程序员 后端

云图说|初识云数据库GaussDB(for Redis)

华为云开发者联盟

数据库 redis 开源 华为云 GaussDB(for Redis)

其实Zookeeper的选举机制也不难理解,今日头条Java后端面试

Java 程序员 后端

EventMachine:高速可伸缩的事件驱动I/O框架_Ruby_Mirko Stocker_InfoQ精选文章