写点什么

Heroku 危机带来的启示

  • 2013-02-21
  • 本文字数:3328 字

    阅读完需:约 11 分钟

这些日子,说 Heroku 处在风口浪尖一点都不为过,先前 InfoQ 就 Heroku 大用户 Rap Genius 的不满做了报道,虽然 Heroku 在官方博客上做了说明,但 Rap Genius 和众多网友并不买账,问题仍在延续,不妨让我们对整件事件做个回顾,看看能够从中得到什么启示。

事件回顾

2 月 13 日,Rap Genius 在其网站上发布了一篇文章,讲述了他们在Heroku 上遇到的问题,并做了分析。问题的导火线是之前为了解决一些JavaScript 的小问题,Rap Genius 在线上做了些ab 基准测试,结果却发现有些页面的响应时间远比Heroku 和New Relic 所报告的时间长。以静态的版权页面为例,Heroku 提供的平均响应时间是40ms,而Rap Genius 测试所得的时间却是6330ms。

Rap Genius 的同学在自己分析的同时,也和 Heroku 的工程师在进行沟通,最后确定问题的原因是处在 Heroku 的路由策略上,关键是 Heroku 的文档并未正确地描述其路由策略(在各个时期的不同文档中,对“智能路由”的描述都是只有在 Dyno 可用时才会将请求路由过去),但实际情况是路由采用了随机分配的策略,不考虑 Dyno 当时的情况,导致大量请求都在 Dyno 上排队,没有得到及时处理。更不幸的是 Heroku 的日志和监控并没有很好地反应实际情况。

这篇文章在 Hacker News Reddit 上一经转发,也获得了不少关注,有网友就在评论中讨论了各种路由算法。在 Rap Genius 的文章中,他们用 R 做了个模拟,原本只需 75 个 Dyno 的一个应用,使用随机路由则需要 4000 个以上的 Dyno。

面对这一情况,Heroku 的危机公关并不成功,虽然 Oren Teich(Heroku 的 GM)及时在 Hacker News 和官方博客上发表声明,承认了他们在 Ruby on Rails 应用上的性能问题,并做了一些承诺;第二天,官方博客上如约发表了具体的技术分析及后续改进的计划。但这些举措都没能让用户满意,暂且不论 3 年来为此多收的费用,至少 Heroku 并没有写出真实的情况:

  1. 模糊了本次事件的时间——Rap Genius 的共同创始人 Tom Lehman 在 2 月 5 日就已经和 Heroku 的 CTO Adam Wiggins 讨论这个问题了,而且在 2 月 8 日发给他了模拟结果,因此 Heroku 并不是在 2 月 13 日才知道这件事情的。更有人早在 2011 年 2 月 17 日就写过博文反应这个问题,还在 Google Group 里进行了讨论,Oren Teich 还亲自答复过,所以 Heroku 早就知道文档和系统实现不符合,存在性能问题。
  2. 模糊了本次事件的影响范围——Heroku 的文中只说了 Bamboo 上的 Rails 应用的性能受到影响,Tom Lehman 调侃到为什么 Cedar 的性能没有受到影响,是因为它用 Thin(Cedar 上默认的 Web 服务器)跑 Rails 的性能就没好过。

问题剖析

在 Heroku 的技术分析里详细描述了造成问题的原因。

Bamboo 是早期的 Heroku 运行时技术栈,运行于 Debian 5.0 之上,提供了两套 Ruby VM——Ruby Enterprise Edition 2011.03 1.8.7-p334 和 MRI 1.9.2-p180,只支持 Ruby on Rails 2.x,使用 Thin 作为 Web 服务器。后来,随着技术的发展,Heroku 将默认的 Bamboo 换成了 Cedar ,从仅支持 Rails 演化为了支持多平台多语言(Ruby on Rails 的默认服务器同样为 Thin)。而问题也正是从这次大的系统架构升级开始的。

Thin 本质上是单线程的 Web 服务器,基于 EventMachine 来做多路复用,通过回调实现请求的并发处理。但要让 Rails 应用充分发挥 Thin 的优势,在编写应用时也要按照 EventMachine 的写法加以修改,对所用的库也有要求。所以,不管是 Bamboo 还是 Cedar,默认情况下还是单线程的,不能很好地支持并发请求处理。如果在 Cedar 中选择 Unicorn ,那么情况则会有所不同。

因为使用 Thin 的 Dyno 无法并发处理请求,所以最初 Routing Mesh 的路由策略是选择只有当 Dyno 可用时才会将请求分配给它。但是由于 Cedar 支持多语言多平台,因此 Routing Mesh 的策略也做了调整,改为了更加通用的随机分配,暂时无法处理的请求在 Dyno 对应的队列中排队,不考虑 Dyno 的负载。对于 Java 应用,这个策略简单有效,但是对于单线程服务器中运行的未经优化的 Rails 应用,这就很成问题了。

更致命的是 Heroku 的文档并没有反映出这一变化,而监控也没能体现这一排队的耗时。原本 Heroku 打算让 Bamboo 的用户继续使用原来的 Bamboo 路由,直到他们做好准备迁移 Cedar。可惜的是随着流量的增加,Heroku 往路由集群里加入越来越多的节点,慢慢的使用新策略的节点占比越来越高,于是 Bamboo 就渐渐地出现了性能的下降。至于 Cedar 上用 Thin 运行的 Rails 应用,自打其上线起,就因随机路由策略而性能不佳,因此 Tom Lehman 的调侃也不无道理。

经验教训

本次事件,作为云服务提供商的 Heroku 有不可推卸的责任,其 CTO 和 COO 在很久前就知情的情况下,没有有效修正该问题,对用户造成了巨大的影响。对于一家云服务提供商而言,在进行大的架构升级前应该进行充分的评估及后续的追踪;在发现问题后,应该及时修正,减少对用户的影响。除了关键的技术实力,还有很多其他细节需要考虑,比如相关的文档和客户支持,本次 Heroku 在这些方面也都做的有欠妥当——文档没有正确反映实际情况,虽然 CTO 和 COO 亲自应答这一问题,但没有实际的后续动作。

在文档方面,同为 PaaS 的 Cloudfoundry 就比较透明,一方面因其开源特性,使用者可以完全了解其运行机制,另一方面有大量的材料能帮助大家更好地使用它。同样以路由机制为例,EMC 中国研究院的颜开撰写的《新版CloudFoundry 揭秘》中详细说明了其路由的实现:nginx 结合Lua 脚本,由Lua 分析请求,直接转发给对应的Droplet,转发是随机的,但是请求中增加了Cookie 信息,由此实现粘性会话,尽量将请求转发到同一个Droplet 上。正是由于这些材料,Cloudfoundry 的使用者可以更好地正确使用Cloudfoundry 的公有云。

在客服方面,好的客服能及时帮助客户解决问题,更能带给客户好的使用体验,而糟糕的客服,则有可能造成客户流失。之前,国内的盛大云因客服的问题遭到投诉,最终用户放弃盛大云,转用其他产品。可见,要做好一个云服务平台,光有技术是远远不够的

虽说使用PaaS 可以降低使用者的运维成本,无需再维护各种基础设施,同时提供适当的冗余,保证可用性。但是,这并不意味着使用者自己不需要下功夫,正确的架构必不可少,还需要一定的投入。

例如,本次Rap Genius 在路由的问题上吃亏,一定程度上也是由于其Web 请求的处理时间过长,才造成了队列中请求积压。对于耗时较长、占用资源的任务应该异步化,而非置于同步的Web 请求中,交由后台专门的Worker 处理更为合适(比如Heroku 上的Worker Dyno 就比Web Dyno 更适合这种任务)。eBay 在其分享中也多次提到了任务的异步化,可见异步化对于一个高负载高可用系统是何其重要

要在故障之初就发现端倪,良好的监控是必不可少的,虽然各家云服务提供商在其产品中都有监控功能,但用户还是应该自己定制适当的监控。除了对服务端的监控,也不能忽视了用户端的监控,如果平时就能察觉用户访问的时间存在异常,那么早就可以发现问题。百姓网在Velocity 大会上就分享过他们的经验,从用户的点击开始获取用户的真实体验。此外,还可以使用 Google Analytics ,国内的监控宝也能对站点进行有效的监控。

随着网站的不断发展,集群也在不断壮大,此时应该将故障视为常态,即使在云端,故障也是不可避免的,AWS 在过去的一年里发生的重大故障就不下三次, 2011 年那次著名的 US-EAST-1 故障甚至还让“天网”的攻击没有发生。在这方面 Netflix 就做的非常领先,他们的“猴子军团”在业内非常有名,通过日常自己制造故障来验证系统能否在真正的故障到来时自行恢复或者降级,降低对用户的影响。

对于云服务的使用者,如果要达到很高的可用度,必须在架构上就将容错和容灾纳入考虑之中,比如节点失效、网络中断、机房断电,甚至是 AWS 可用区整个故障。公有 PaaS 在这方面为用户提供了一些支持,但是在 AWS 可用区故障容灾方面应该还没有很好的支持,比如跨可用区的数据冗余,主从如何选择都是需要考虑的问题,需要用户自己来继续完善。

要做好一个云服务平台需要投入很多的精力与成本,而要用好这个平台,在其中上搭建站点为最终用户创造更多价值也并绝非易事,希望这次 Heroku 的事件能给大家带来一些启示,不知读者朋友您又有何经验可以分享?

2013-02-21 21:3314019
用户头像

发布了 135 篇内容, 共 63.8 次阅读, 收获喜欢 43 次。

关注

评论

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

吹爆!GitHub上久经不衰的经典教程:Springboot精髓参考指南手册

Java

又快又全的云IT资源运维软件重点推荐-行云管家!

行云管家

云管平台 云资源 IT资源 IT运维

爱尚拼购系统软件开发搭建

乐活星际系统软件开发资料

IPFS/Filecoin项目的未来趋势怎么样?投资Filecoin挖矿有风险吗?

IPFS fil币 ipfs挖矿 fil挖矿 fil矿机

前端通讯协议大比拼:WebSockets和HTTP

devpoint

HTTP websocket HTTP2.0 7月日更

基础SQL的实现

卢卡多多

7月日更

推荐大家一个阅读全球计算机论文的好RP

奔着腾讯去

网络攻防学习笔记 Day75

穿过生命散发芬芳

网络攻防 7月日更

金九银十马上要来了!我准备了1套完整版一线大厂面试真题送给大家

Java 编程 程序员 架构 面试

数仓架构的持续演进与发展 — 云原生、湖仓一体、离线实时一体、SaaS模式

阿里云大数据AI技术

ATS挖矿系统开发案例

Redis - Cluster - gossip&故障转移

旺仔大菜包

redis cluster

Pomo币挖矿APP系统开发介绍

养牛达人APP系统开发资料

hdfs namenode的故障恢复

五分钟学大数据

hdfs 7月日更

Filecoin矿机挖矿APP系统开发

获客I3O6O643Z97

区块链+ 云算力挖矿源码 fil挖矿 fil矿机

《持之以恒的从事运动》八

Changing Lin

疯了吧!这帮人居然用 Go 写“前端”?(二)

尔达Erda

开源 云原生 大前端 PaaS Go 语言

英特尔在异构计算前加了一个“超”字,凭什么?

E科讯

芒果微视系统软件开发内容

市值管理机器人开发,搭建量化交易机器人

Geek_23f0c3

机器人 市值管理机器人开发 #区块链# 量化机器人

“此苹果非彼苹果”看意图识别的那些事儿

百度大脑

人工智能 飞桨 数据抽取

你也许连删库跑路都不会

喵叔

7月日更

《淘宝技术这十年》读后总结

淘宝架构 淘宝技术这十年

Alibaba全新出品JDK源码学习指南,面面俱到,没有一句废话

Java 编程 架构 面试

在线医疗不容错过

anyRTC开发者

音视频 WebRTC 实时通讯 在线医疗

VGC算力挖矿APP系统开发

获客I3O6O643Z97

挖矿 #区块链# PHA质押挖矿

模块二作业

江南巴飞特

Mysql,RedisCluster,Kafka,Mongo笔记分享

鲁米

安装

傻眼了,我粗略造了一个命令执行的绕过方法居然被同事嫖走了

网络安全学海

黑客 网络安全 信息安全 渗透测试 漏洞分析

Heroku危机带来的启示_Ruby_丁雪丰_InfoQ精选文章