NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

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

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

关注

评论

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

CnosDB容灾方案概述

CnosDB

开源 时序数据库 tsdb CnosDB

Navicat for MongoDB mac(MongoDB 数据库管理和开发)v16.3.4激活版下载

iMac小白

解读 $mash 通证 “Fair Launch” 规则,公平的极致?(Staking 玩法)

EOSdreamer111

DevOps|产研运协作工具链上的皇冠-项目管理工具

laofo

项目管理 DevOps cicd 敏捷开发 研发效能

有什么安全处理方案可以有效防护恶意爬虫

德迅云安全杨德俊

爬虫 安全 CDN

文心一言 VS 讯飞星火 VS chatgpt (173)-- 算法导论13.3 2题

福大大架构师每日一题

福大大架构师每日一题

webSocket的使用详解。

百度搜索:蓝易云

Linux 运维 Web websocket 云服务器

详解Sei V2的并行EVM逻辑与叙事,添加主网至Bitget钱包

长安区块链

URL Manager Pro for Mac(浏览器标签管理应用)v6.4.2激活版下载

iMac小白

小红书 X WSDM 2024「对话式多文档问答挑战赛」火热开赛!

小红书技术REDtech

人工智能 数据挖掘 搜索 信息检索 WSDM

解读 $mash 通证 “Fair Launch” 规则,公平的极致?(Staking 玩法)

股市老人

最大输出 18W,集成 Type-C PD 输出和各种快充输出协议

智趣匠

服务器日志处理,文件截取关键字教程。

百度搜索:蓝易云

云计算 Linux 运维 云服务器 ECS

Avdshare Video Converter for Mac(视频转换器)v7.5.2激活版下载

iMac小白

AudFree Audio Converter for mac激活版下载

iMac小白

【Java技术深入解析】「核心技术提升」最流行的Java模拟框架Mockito入门指南(Java单元测试)

洛神灬殇

Java Mock 服务 技术分析 2024年第四篇文章

分布式系统设计: 从1千到10亿用户的跨越

俞凡

架构

Linux route命令实战:route 命令实战教程,配置静态路由,删除路由表项

百度搜索:蓝易云

云计算 Linux 运维 云服务器 Route

工赋®新思直播预告 | 1月9日晚19:00,基于运营数字孪生的工艺质量控制与优化

工赋开发者社区

通过聚道云软件连接器实现钉钉与自研主数据系统的完美融合

聚道云软件连接器

案例分享

IDC报告:网心科技以11.8%的市场份额位居中国边缘公有云第三

网心科技

一文了解 DeFi 原生公链 Sei,以及钱包添加教程 什么是Sei?

大瞿科技

Sei新手完全指南科普,以及钱包介绍测评(bitget)

BlockChain先知

Eassiy Data Recovery for mac(硬盘数据恢复工具)v5.1.6激活版下载

iMac小白

Receipts for Mac(财务文件管理)v1.15正式激活版下载

iMac小白

2024-01-06:用go语言,在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧 在桥上有一些石子,青蛙很讨厌踩在这些石子上 由于桥的长度和青蛙一次跳过的距离都是正整数 我们可以把独木桥

福大大架构师每日一题

福大大架构师每日一题

Sei新手完全指南科普,以及钱包介绍测评(bitget)

石头财经

FSNotes for mac(mac文本处理工具)v6.6.4中文免激活版下载

iMac小白

分层架构最佳实践

俞凡

架构

工信部:5项工业互联网平台国家标准正式发布实施

工赋开发者社区

DRmare Audio Converter Mac v2.9.0激活版下载

iMac小白

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