QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

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

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

关注

评论

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

以开发之名 | bilibili会员购让IP在眼前动起来

HarmonyOS SDK

FinClip | 2022 年 10月产品大事记

FinClip

速报|StarRocks亮相云栖大会,携手阿里云EMR 打造极速数据湖分析新体验

StarRocks

数据库

Spring Boot「23」DAO 模式

Samson

Java spring Spring Boot 学习笔记 11月月更

论坛回顾|FlyFish 一周年开源圆桌论坛圆满落幕

云智慧AIOps社区

开源项目 开源软件 开源治理 开源贡献 开源运营

数据中台选型必读(一):元数据管理是数据使用与共享的根基

雨果

数据中台

订单里的充值卡消费和积分抵扣怎么处理?

产品海豚湾

产品经理 产品设计 电商系统 分析设计 11月月更

软件测试面试真题 | 常见网络状态响应码

测试人

软件测试 面试题 状态码 测试开发

Edge 浏览器提供了一个站点信息的按钮

HoneyMoose

使用 Goland 开发 dubbogo 项目时如何自动快速格式化 import 代码块

apache/dubbo-go

数仓、湖仓、数据中台都没解决的企业数字化难题,却被它解决了

雨果

数据中台 数据仓库 DaaS数据即服务 数仓一体

如何快速优雅的用Know Streaming创建Topic

石臻臻的杂货铺

11月月更

Web渗透测试攻防之浅述信息收集

网络安全学海

网络安全 安全 信息安全 渗透测试 信息收集

深圳区块链交易所的交易方式及开发搭建

W13902449729

深圳区块链交易所开发

2022干货来袭!阿里大佬“亲码”Java全线笔记,差距不止一点点

程序知音

Java java面试 后端技术 Java面试题 Java面试八股文

思码逸 X 贝壳:用代码分析,升级既有效能度量体系

思码逸研发效能

数据 研发效能 研发管理工具

深圳区块链交易所app开发、数字资产交易系统搭建

W13902449729

深圳区块链交易所app

沙龙预告 | EPM 业财一体-合并报表(11月8日 14:00)

信通院IOMM数字化转型团队

数智化转型 EPM 业财一体 沙龙预告

金融服务的超级App

FinClip

走向IPv6,阿里巴巴IPv6规模化部署实践

阿里技术

ipv6

InnoDB与MyISAM的使用,该如何选择?

想要飞的猪

小白一键出片,三分钟成为修图大师的秘诀。

淋雨

ps LR 磨皮插件 滤镜插件

在线KMS激活windows系统

源字节1号

软件开发 小程序开发

快速应用程序开发

世开 Coding

软件开发 快速开发 敏捷精益

华为云从入门到实战 | 云容器服务

TiAmo

华为 华为云 云开发 11月月更

数据中台选型必读(二):数据中台如何搭建元数据管理中心

雨果

数据中台

Jenkins 构建的时候提示 DOCKER_HOST 错误

HoneyMoose

Go 云原生实战:如何增加应用配置模块

宇宙之一粟

云原生 配置 Go 语言 Web应用开发 10月月更

华为开发者大会2022即将召开 精彩主题演讲线上同步直播

科技汇

MSE 风险管理功能发布

阿里巴巴云原生

阿里云 云原生微服务

活字格低代码开发平台怎么样?靠谱吗?

优秀

低代码平台

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