2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

范凯观点:Ruby 社区应该去 Rails 化

  • 2013-03-28
  • 本文字数:2821 字

    阅读完需:约 9 分钟

InfoQ 中文站报道过一些公司从 Ruby 转移到其他语言的新闻,包括 Iron.io 从 Ruby 迁移到 Go:减少了 28 台服务器并避免了连锁故障从Ruby 向Java 的迁移帮助Twitter 挺过了美国大选在LinkedIn 的Ruby on Rails 和Node.js 对决。最近,IT 元老范凯在博客中详细地分析了Rails 目前在Web 服务方面的局限和原因,针对“继续沿用Ruby on rails 重写或者重构应用,性能可能会有一两倍的提升,但无法弥合10 倍以上的性能差距,难道说Ruby 真的如此不堪吗?注定要被Node.js 或者Go 所取代吗?”这个问题给出了自己的观点,即:使用其他Ruby 轻量级框架取代Rails,而不是使用Node.js 和Go 取代Ruby。

针对Ruby 的性能问题,范凯首先做了澄清,存在性能问题的是Rails,而不是Ruby 语言本身,他引用了Ruby 的纤程框架 Goliath 的实际应用数据:

  • VPS 上总共使用了 16 个 CPU 内核,跑了 16 个单进程实例
  • 每个进程实例稳定消耗 50MB 内存
  • Web 框架使用 Goliath, URL 分发是 grape,数据库访问使用 ActiveRecord,缓存使用 Redis
  • 应用吞吐量达到了 1800 request/s

这个数据意味着一台配备了 4 颗 4 核 CPU,2G 内存的服务器,每天可以处理 1.5 亿次 web 请求。由此可见,Ruby 完全可以做到高并发 IO 的应用。问题主要不在 Ruby 解释器上,而在 Rails 框架上。更准确的说就是, Ruby on R****ails 作为一个 full-stack 的 web 开发框架,并不适合用来开发 Linkedin 和 Iron.io 的后台 web 服务,从某种意义上来说,属于 Rails 的时代已经过去了。

范凯表示:移动时代,Web 服务将取代 Web 网站。为什么 Rails 不适合 Web 服务呢,他认为主要原因包括:

  • Rails 调用堆栈过深,URL 请求处理性能很差Rails 的设计目标是提供 Web 开发的 最佳实践 ,所以无论你需要不需要,Rails 默认提供了开发 Website 所有可能的组件,但其中绝大部分你可能一辈子都用不上。其中最夸张的是ActionDispatch::RequestIdmiddleware,只有在大型应用部署在群集环境下进行线上调试才可能用到的功能,有什么必要做成默认的功能呢? Rails 的哲学是:提供最全的功能集给你,如果你用不到,你自己手工一个一个关闭掉 ,但是这样带来的结果就是默认带了太多不必要的冗余功能,造成性能损耗极大。
  • Rails 加载的框架和依赖库过多,内存消耗过度。Rails 自身依赖库非常多,造成的结果就是 Rails 应用持续运行以后内存消耗非常高。举个例子:如果你用到了 Rails 的 asset pipeline 功能,那么项目需要依赖一个 JS 引擎来编译 JS 和 CSS,默认会使用 libv8 这个库。尽管只是编译阶段使用 libv8,运行期并不需要它,但是仍然会加载 libv8,这意味着你的每个 ruby 进程会多占 20MB 内存。在我们其中一个大项目上,总共开了 40 个 Ruby 进程,直接浪费了 800MB 内存。于是我们不得不在生产服务器上安装了 Node.js,替换了 libv8。此外,一旦其中某个依赖库有内存泄露,整个应用也可能出现内存泄露,这种内存泄露是很讨厌的事情,Rails 如此肆无忌惮不加限制的使用第三方依赖库也是一个潜在的隐患。
  • Rails 传统多进程模型的 IO 并发能力很低。Rails 的多进程并发模型的 IO 并发能力很低,开多少个进程,就只能同时响应多少个并发请求,但 Ruby 进程的内存消耗是很大的,多进程调度的 CPU 开销也很高,这决定了单台服务器上能开的进程数是非常有限的,一般不会超过 30 个。但是对于 Web Service 类型的应用,需要很高的 IO 并发处理能力,传统 Rails 多进程很容易就会出现负载的瓶颈。从 Rails4.0 开始,默认也开启了多线程模式,也可以支持多线程方式运行 Rails 应用。但就目前来说,Rails 使用多线程,还面临一些兼容性问题:大量的 Rails 插件和代码不是线程安全的,在多线程模型下运行,会出现意想不到的 bug;另外 Rails 的多线程应用尚未得到广泛应用,可能会有潜在的 bug。

不用 Rails,Ruby 社区又能用什么呢?范凯提供了自己的建议:

  • Sinatra ——Sinatra 本身也是 Ruby 社区非常流行和著名的轻量级 Web 框架,核心源代码不超过 1000 行,文档只有 1 页。对于 Rails 开发者来说,花了几个小时,就可以快速使用 Sinatra 开发 Web Service 了。Sinatra 对多线程支持的非常好,可以用 rainbows 来跑多线程 Sinatra,IO 并发处理能力很好。Github 也是用它来提供开放 API 服务的。我自己写了一个 Sinatra 的项目模版,如果你用 Sinatra 开发 Web Service,可以参考。
  • Padrino ——Padrino 是一个基于 Sinatra 之上的轻量级 Web 框架,在 Sinatra 基础之上提供了命名路由,模块化项目组织,页面 helpers 和 generators 等等。Padrino 是一个高度模仿 Rails 的框架,API 的命名和 Rails 很像,Rails 开发者花 1-2 天看看文档就可以快速上手开发了。Padrino 相比 Rails 易学易用,多线程支持良好,性能比 Rails 好很多,开发 Website 推荐使用。我自己的网站也是用 Padrino 开发的,源代码在: robbin_site
  • Goliath ——Goliath 是一个 Ruby 的纤程开发框架,性能非常好,作者本身是在开发 PostRank 产品过程中开发的 Goliath。PostRank 是一个用户社交行为实时跟踪工具,需要很高的性能来支撑,PostRank 被 Google 收购了,作者现在在 Google 工作。Goliath 适合用来开发对性能非常敏感的 Web Service 或者 real-time 的应用,但使用 Goliath 有一些门槛,你不能使用普通的阻塞 IO 库,必须使用作者封装的一些纤程的库。

所谓的“去 Rails 化”,范凯认为不必大惊小怪:

学习 Rails 无非意味着你花了时间熟悉 ActiveRecord 和 ActionPack 以及相关库的功能而已,所谓去 Rails 化也仅仅只是放弃使用 ActionPack,换一个更轻量级更简单的 URL 路由处理器,例如换成 Grape,Sinatra,Padrino 或者 Camping 而已。这对一个长期使用 Rails 的 Ruby 开发者来说,应该是举手之劳的事情。所以自己动手,根据实际应用场景挑选最合适的组件。例如 ActionPack 不太适合写 Web Service,那我换成 Sinatra 就行了,但是 ActiveRecord 照常用,这并不需要你付出多少学习成本,更不需要你放弃什么。

目前有一些公司从 Ruby/Rails 转向 Node.js 和 Go,范凯经过调研,认为 Ruby 更适合自己:

  • 用 Sinatra 或者 Goliath 这样的轻量级框架写 Web Service,性能已经足够好了,特别是 @黄志敏的案例证明,16 核已经可以支撑每天 1.5 亿次请求了,对我来说已经不太可能遇到超过这个负载量的应用了。而 Ruby 的开发效率,代码表达能力和可维护性对我来说还是很重要的。
  • Node.js 的 Event IO 编程风格在我看来是“反人类”的,极其变态的。用来写代码上规模的应用,代码的可读性和可维护性都很差。Event IO 是很底层的技术,我很难理解为何不封装成 coroutine 来使用。Node.js 只适合用来开发 real-time 类型的应用。
  • Go 的主要问题在于现阶段还不成熟:一方面 Go 自身还在演进当中;另一方面 Go 的类库还是过于贫瘠了,用来开发项目还是需要自己写很多东西的,感觉很不方便。

有关范凯完整的论述,可以查看博客原文。欢迎 InfoQ 读者发表自己的看法。

2013-03-28 01:096068
用户头像

发布了 501 篇内容, 共 282.9 次阅读, 收获喜欢 64 次。

关注

评论

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

YashanDB|yasql 使用 as sysdba 登录失败的排查思路

数据库砖家

数据库

【ITSM运营】问题管理全景图:从识别到复盘的闭环优化体系

嘉为蓝鲸

AIOPS ITSM 智能运维

YashanDB 登录报 YAS-02143:密码中含特殊字符的处理方法

数据库砖家

数据库

使用 Druid 查询 GIS 空间数据时报 read time out 的排查与规避方法

数据库砖家

数据库

Hive 初始化 YashanDB 报错 YAS-04209 的原因与处理办法

数据库砖家

数据库

AARRR模型是什么,包括哪些阶段?一文弄懂PM必备的思维模型!

职场工具箱

人工智能 产品 AI 产品经理 AIGC

深入解析金仓数据库的模式:创建、管理与应用

金仓技术

KingBase 金仓数据库

Timer-XL 时序大模型论文入选 ICLR 2025,通用与时序场景性能均达到领先水平

Apache IoTDB

YashanDB|启动 yasom 报错 sqlite connection error 的处理思路

数据库砖家

数据库

一键多环境构建——用 Hvigor 玩转 HarmonyOS Next

鸿蒙魔法师

鸿蒙 HarmonyOS HarmonyOS NEXT Harmony5

YashanDB 使用 imp 导入时报 YAS-08023 的原因与处理办法

数据库砖家

数据库

Python 查询 GBK 编码的 YashanDB CLOB 字段数据被截断的原因与修复

数据库砖家

数据库

RAG检索实践:多路检索(PostgreSQL环境准备)

程序员架构进阶

全文检索 5月日更 大模型 PgSQL rag

埃文科技大模型领域研究再获突破!两篇创新论文入选国际顶会KDD 2025

郑州埃文科技

大模型

SD-WAN怎么实现企业海外网络访问?

Ogcloud

SD-WAN 企业组网 海外网络加速 海外网络访问 海外网络连接

虚拟机中的 YashanDB 无法从本机访问的处理办法

数据库砖家

数据库

YashanDB 安装时报 SSH 认证失败错误的处理方法

数据库砖家

数据库

YashanDB 使用 listagg 报 YAS-02511 的原因及解决方案

数据库砖家

数据库

TEN 开源超轻量 VAD 和全双工对话轮次检测模型;Stability AI 发布全新端侧音频生成模型,无版权风险丨日报

声网

使用 JDBC 批量插入 YashanDB GIS 空间数据的示例

数据库砖家

数据库

想要给软件加点功能啥的,源码是必须要有的

程序员郭顺发

从China P&E 2025 看闪迪创作者系列如何提升生产力

极客天地

RocketMQ高级使用

量贩潮汐·WholesaleTide

RocketMQ

天润融通重磅亮相AWS香港峰会,阐述“业务专家 + AI员工”新模式

天润融通

YashanDB|yasboot 执行 cluster status 命令失败的处理办法

数据库砖家

数据库

YashanDB 收集统计信息时报 YAS-00507 错误的处理方法

数据库砖家

数据库

通过 JDBC 向 YashanDB 批量插入空间数据的标准写法

数据库砖家

数据库

从被动响应到主动预防:AI驱动下的运维流程革命

嘉为蓝鲸

AIOPS 智能运维 DeepSeek

告别传统运维繁琐:OpsPilot 对话式交互让 K8s 集群管理更轻松

嘉为蓝鲸

k8s 智能运维 #WeOps OpsPilot

如何在 YashanDB 备机上安全进行备份与恢复操作

数据库砖家

数据库

可观测性方案怎么选?SelectDB vs Elasticsearch vs ClickHouse

SelectDB

elastic 可观测性 实时数仓 Clickhouse 数据库 大数据

范凯观点:Ruby社区应该去Rails化_Ruby_崔康_InfoQ精选文章