写点什么

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:527383
用户头像

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

关注

评论

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

Flask框架-请求与响应

霍格沃兹测试开发学社

ThreadLocal实践案例两则

FunTester

飞书深诺数仓低代码方案实战

飞书深诺技术团队

时序数据高基问题揭秘:根因分析与解决之道

Greptime 格睿科技

时序数据库 云原生数据库 国产时序数据库 高基问题

接口测试|Postman环境变量&全局变量设置

霍格沃兹测试开发学社

Postman

直播精华回顾|《2023中国营销+AIGC市场研究报告》照进产业现实

TE智库

UI自动化 - 如何判断一个页面上元素是否存在?

霍格沃兹测试开发学社

使用低代码平台提高生产力

树上有只程序猿

低代码 生产力 全栈开发 JNPF

校源行 | 2023年开放原子校源行开源大使培训圆满结束,考试时间正式公布

开放原子开源基金会

开源

saas堡垒机定义以及优势简单说明-行云管家

行云管家

SaaS 堡垒机 saas堡垒机

开放原子开源基金会代表团出席Open Source Congress并参与专题研讨

开放原子开源基金会

接口测试|postman模拟请求头&界面的响应信息

霍格沃兹测试开发学社

Postman

GPTCache 悬赏令!寻找最佳捉虫猎手,豪华赏格等你来拿!

Zilliz

Zilliz AIGC ChatGPT LLM gptcache

一款好用的低代码开发平台是什么样的?

高端章鱼哥

低代码 低代码平台 JNPF

接口测试|Postman持久化保存

霍格沃兹测试开发学社

Postman

接口测试|Postman发送带参数的Get请求

霍格沃兹测试开发学社

基于低代码平台快速搭建应用

互联网工科生

低代码 低代码开发 JNPF java低代码开发平台

让数据管理由繁至简的低代码开发平台

力软低代码开发平台

马上解锁 StarRocks 存算分离,降本增效无需等!

StarRocks

数据库 大数据 数据仓库 存算分离

校源行|开放原子开源社团(山东大学)授牌仪式隆重举行

开放原子开源基金会

开源 山东大学

开放原子开源基金会TOC(技术监督委员会)第七十九次全体会议

开放原子开源基金会

开源

利用文心千帆打造一个属于自己的小师爷

为自己带盐

大语言模型 文心千帆

接口测试|postman发送POST请求

霍格沃兹测试开发学社

Postman

接口测试|Postman设置断言

霍格沃兹测试开发学社

Postman

pycharm环境配置

霍格沃兹测试开发学社

Flask框架-接口路由

霍格沃兹测试开发学社

【十万个等保小知识】等保测评报告是在等保整改之后发吗?

行云管家

等保 等级保护 等保测评 等保整改

DLRover 在 K8s 上千卡级大模型训练稳定性保障的技术实践

AI Infra

人工智能 开源 AI 开发者 kubernetes 运维

喜讯! WorkPlus入选中国信通院数字产品“2023全景图”!

WorkPlus

单元测试|unittest生成测试报告

霍格沃兹测试开发学社

Python

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