速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

范凯观点: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:095380
用户头像

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

关注

评论

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

Keepalived+HAProxy 搭建高可用负载均衡

CTO技术共享

基于KubeEdge的边缘节点分组管理设计与实现

华为云开发者联盟

云计算 云原生 后端

Databend 源码阅读系列(二):Query server 启动,Session 管理及请求处理

Databend

query query分析 大数据 开源 #开源 databend

软件测试 | 测试开发 | 白盒测试方法论

测吧(北京)科技有限公司

白盒测试

官宣!华为云GaussDB两大数据库通过中国信通院多项评测

科技怪咖

华为云发布《云原生2.0架构白皮书》,GaussDB技术再升级

sofiya

设计模式的艺术 第五章工厂方法设计模式练习(设计一个程序来读取各种不同类型的图片格式,针对每种格式都设计一个图片读取器)

代廉洁

设计模式的艺术

数字藏品系统开发:NFT系统开发

开源直播系统源码

数字藏品 数字藏品软件开发 数字藏品源码出售 数字藏品开发

Java培训的主要内容是什么?

小谷哥

从西方舶来品到中国智造,美的R6强势引领嵌入式厨电风向标

Geek_2d6073

JPEX 围绕世界杯打造“平台 + 运动”新生态,为 JPC 深度赋能

股市老人

百万粉丝养成记:写作4步法,解决文案创作的80%问题!

图灵教育

写作 脑科学

直播预告 | Homebrew 作者 Max Howell:如何打造杰出的开发者工具

玩转Devop和研发效能DevStream/DevLake

#开源

4步教你做一个煤气安全提示神器

华为云开发者联盟

云计算 后端 物联网 IoT

华为云GaussDB(for Redis)揭秘:谁说Redis不能存大key

科技怪咖

中大型现代服务行业的ERP,Telework现代服务中台

sofiya

华为云发布业界首个《云原生数据库白皮书》 重新定义数据新范式

科技怪咖

【小程序项目开发-- 京东商城】uni-app之商品列表页面 (下)

计算机魔术师

8月月更

defi质押挖矿dapp系统开发智能合约部署详解

开发微hkkf5566

TDesign「issue一夏·疯狂的代码&设计」主题赛事火热进行中

TDesign

腾讯 前端

软件测试 | 测试开发 | App常见bug解析

测吧(北京)科技有限公司

bug

面试官:你知道MySQL和Linux操作系统是如何改进LRU算法的吗?

程序员小毕

Java MySQL 程序员 面试 LRU

教育部“产学合作协同育人”项目华为云GaussDB项目入选名单公布

sofiya

软件测试 | 测试开发 | App测试时常用的adb命令你都掌握了哪些呢?

测吧(北京)科技有限公司

app测试

MobTech短信验证 Android端快速集成

MobTech袤博科技

android android-studio 短信验证

使用华为云GaussDB(for Redis)实现二级索引

科技怪咖

【微信小程序开发】自定义tabBar案例(定制消息99+小红心)

计算机魔术师

8月月更

DevOps技术产品链

CTO技术共享

SRE 运维体系 CTO技术共享

CTO技术共享

百万粉丝养成记:写作4步法,解决文案创作的80%问题!

图灵社区

写作 脑科学

融云超级群的「同城社交平台」应用实践

融云 RongCloud

社交网络

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