【QCon】精华内容上线92%,全面覆盖“人工智能+”的典型案例!>>> 了解详情
写点什么

移动后端支持平台 Parse 将 API 由 Ruby 迁移到 Go

  • 2015-06-16
  • 本文字数:1856 字

    阅读完需:约 6 分钟

Charity Majors 是移动后端支持平台 Parse 的工程师。近日,他撰文介绍了他们将API 从Ruby 迁移到Go 的过程。

2011 年, Parse 借助 Ruby on Rails 快速推出了第一个版本。他们用 Unicorn 作为 HTTP 服务器,用 Capistrano 部署代码,用 RVM 管理环境,并用许多开源 gems 处理 YAML 解析、oAuth、JSON 解析、MongoDB 及 MySQL 等方面的工作。此外,他们还用 Chef 管理他们的基础设施。

起初,平台运行良好。但随着代码库的增长,部署时间越来越长,Unicorn 服务器无法很平稳地重启。到 2012 年底,他们有 200 个 API 服务器运行在 m1.xlarge 类型的实例上,每个实例 24 个 Unicorn 工作进程。该平台每秒需要为来自 60000 个移动应用的 3000 个请求提供服务。一次完整部署或回滚需要 20 分钟。另外,在通常的 Ruby on Rails 设置中,工作进程池大小固定,每个工作进程一次只能处理一个请求。随着 API 流量和应用数量的增加,“一个请求一个进程”的 Rails 模型开始无法满足平台的扩展需求,而增加数据库和工作进程也增加了故障点和性能退化的可能。

于是,他们认为,他们需要迁移到一个完全不同于 Rails 的异步工作模型。他们对比了如下选项:

  • EventMachine:绝大多数 Ruby gems 都不是异步的,而且许多不是线程安全的,所以经常很难找到一个库可以异步地处理一些常见任务。
  • JRuby:JRuby 从根本上说还是 Ruby,同样缺少异步库支持。而对于 Java,他们的后端或 Ops 团队不愿意部署和调优 JVM。
  • C++:他们现有的 C++ 代码已经难以调试和维护。与其它现代编程语言相比,C++ 开发的效率不是很高。C++ 也缺少一些他们需要的库,比如 HTTP 请求处理。C++ 可以处理异步操作,但并不好用。
  • C#:C#有最好的并发模型,并且支持 Async 和 Await。但真正的问题在于,Linux 对 C#开发的支持不够好,缺少一些与常用开源工具互操作的库。如果选择 C#,那么他们就需要对工具链做重大调整。
  • Go:同 C#一样,Go 也在底层内置了异步操作。MongoDB Go 驱动程序可能是现有最好的 MongoDB 驱动程序,而与 MongoDB 的复杂交互是 Parse 的核心所在。Goroutines 比线程更轻量级。

最终,他们选择了 Go,用它重写了 EventMachine 推送后端、核心 API 服务器,实现了 Rails 中间件的处理功能,结果:Parse 平台的可靠性提高了一个数量级;API 不再因为数据库和后端服务的增加而日益变得脆弱;由于去掉了大量的 gems 和隐含假设,代码库变得更干净;Ops 团队不用每周处理多次 Ruby API 故障了;预分配的 API 服务器池缩减了约 90%;移除了孤立的 Rails API 服务器筒仓,简化了架构;完整集成测试的时间由 25 分钟缩减至 2 分钟;完整 API 服务器部署(包含滚动重启)的时间由 30 分钟缩减至 3 分钟;Go API 服务器启动更平稳。

虽然 Parse 成功地实现了迁移,但是许多网友都认为 Majors 给出的选择理由并不充分。网友 pron 指出,JVM 易于监控、控制、调试和性能分析。在大多数情况下,JVM 调优只需要设置 GC 方式、最大堆大小和新生代比率三个值。对此,Majors 的答复是,“我们讨厌有关 Java 和 JVM 的一切”。网友 headius 则为 Parse 团队没有试用 JRuby 感到可惜,因为单个 JRuby 实例就可以处理成百上千的并发请求,而且不需要采用异步方式。他认为,JRuby 团队不需要重写就可以解决 Parse 的问题。网友 Zazi Bazuka 则这样评论道:

我讨厌这篇博文,攻击 Ruby 成了现在的一种趋势。但攻击总是来自不了解 Ruby 生态系统的人。为什么不使用 Puma 或其它多线程服务器?!为什么使用 EventMachine?互联网上到处都是不应该使用它的文章,你们应该使用 celluloid.io 代替它。

Majors 的文章在 Hacker News 上也引发了激烈的讨论,其中许多网友同样对 Parse 的选择过程存在疑问。网友 aikah 就表示:

当了解业务域和性能问题时,Go 是一个不错的迁移目标。但是,我不推荐初学者用它构建安全的 Web 应用程序,因为……Go 确实不适合用于传统 Web 站点的快速开发。让我吃惊的是,Parse 用 Rails 编码,我原以为他们以 Node.js 为基础构建,因为 Cloud Code 用了 JS。

对此,lacker 答复说:

我们考虑过它。那时,一个很大的 Node 代码库看上去很难维护。不过,工具比那时好了。如果我们现在重新讨论,我认为,采用 Node 的理由会更令人信服,如果我们等到 ES6 成为标准后再讨论,理由还会更充分。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-06-16 21:453025
用户头像

发布了 1008 篇内容, 共 372.2 次阅读, 收获喜欢 340 次。

关注

评论

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

微服务架构中分布式事务实现方案怎样何取舍【转发】

古月木易

微服务

架构师训练营 - 食堂就餐卡系统设计

Pontus

极客大学架构师训练营

作为一个架构师,我是不是应该有很多职责?

架构师修行之路

程序员 架构 架构师

Facebook缓存技术演进:从单集群到多区域

伴鱼技术团队

架构 系统架构 分布式系统 缓存穿透 cache

第一周架构师总结

不在调上

架构师训练营第一周总结

hifly

软件架构 架构师 极客大学架构师训练营 #总结#

区块链如何打通征信行业的“任督二脉”?

CECBC

CECBC 区块链技术 征信 数据共享

提高 TCP 性能的方法,你知多少?

小林coding

TCP 性能优化 高并发 网络

食堂打卡系统架构设计文档

Frank Zeng

架构师训练营第1周作业——食堂就餐卡系统设计

在野

极客大学架构师训练营

架构师必备技能(灵魂拷问篇)

鲁米

架构师

架构师训练营第一周学习总结

jiangnanage

架构设计

架构师训练营-第一周学习总结

zcj

极客大学架构师训练营

谈反应式编程在服务端中的应用,数据库操作优化,从20秒到0.5秒

newbe36524

C# Reactive netcore

产品经理越来越不值钱了吗?

Neco.W

产品 产品经理

架构师训练营-开营

zcj

极客大学架构师训练营

食堂就餐卡系统设计

鲁米

架构设计

数据结构与算法之基础入门

shirley

数据结构 算法

【架构师训练营】第一个周课程总结

Mr.hou

极客大学架构师训练营

TOGAF认证自学宝典

涛哥 数字产品和业务架构

架构 企业架构

FPGA

Kevin Z

译-面向前端开发人员的Docker入门指南

费马

Docker Linux 容器 运维 大前端

架构师训练营-第1课总结-202006-架构设计

👑👑merlan

架构设计 UML #总结#

作业1 餐卡系统设计

Geek_2e7dd7

架构师训练营第一周课堂学习总结

Frank Zeng

c# 之linq——小白入门级

moonlucy

二叉树视频|留美六年毅然归国,85 后技术 VP 金超:我想把工业智能做好

二叉树视频

写作平台 二叉树 年少有为

架构师训练营-第一周-学习总结

Anrika

极客大学架构师训练营 架构总结

架构师训练营-第一周作业

zcj

极客大学架构师训练营

系统梳理主流定时器算法实现的差异以及应用

奈学教育

定时器

系统梳理主流定时器算法实现的差异以及应用

古月木易

定时器

移动后端支持平台Parse将API由Ruby迁移到Go_Ruby_谢丽_InfoQ精选文章