Heroku 高可用性管理之道 —— QCon 伦敦站演讲摘要

  • Fabian Lange
  • 曹如进

2012 年 4 月 1 日

话题:Java云计算DevOps语言 & 开发架构

高可用性对于 PaaS 解决方案来说是一个相当大的挑战,因为不仅硬件,还包括软件基础架构服务,都需要在所有时间里处于可用状态。Mark McGranaghan 在QCON 伦敦站演讲中(下载 PDF 幻灯片),讲解了Heroku为提供一直可用的 PaaS 系统所使用到的模式。

Mark 说在看他来,那些模式可以归为两方面:

  1. 带有特定设计观念的架构方面;
  2. 描述人与软件如何交互的社会技术(Socio-Technial) 方面。

按照 Mark 的说法,在涉及 HA 应用程序部署和运作时,人的因素常常被低估。Heroku 架构方面的许多观念取自Erlang,下文的一些例子将更清晰地展示这点。

架构方面

在 Heroku 上部署应用程序可以获得 Heroku 提供的众多服务而无需自行处理。例如,路由 HTTP

请求就是一个由 Heroku 管理的服务。事实上,应用程序本身也做不到这点,因为它运行于 Heroku 上的多个实例之上,并且由监督者(supervisors)进行监控,其中这些监督者可以将它们重启。因此,虽然应用程序并不知道自己在哪里运行,但是 Heroku 路由网知道应用程序每个实例的位置,因此它可以将 HTTP 流量对应地进行定向。路由网本身由多个云端实例组成,如果需要,它也可以被监督、扩展或重启。这套模式遵循了 Erlang 的错误内核(error kernel)概念。所有的服务均受到监督,并且它们的监督者同样也受到监督。任何事情都可以失败并进行重启。这样做减轻了 Heroku 和运行于 Heroku 之上的应用程序关于错误处理的负担。

由于任何事情都允许失败,因此应用程序应当使用一种平滑降级(graceful degrading)的方式进行设计。Mark 给出了一些例子显示实践中的一般做法:

可靠消息传输(Reliable Messaging)

在传统的消息代理(Message broker)架构中,也存在单点故障:消息发往的终端点(endpoint)需要处于可用状态。Heroku 采用了一种叫做”一处发布 / 多处订阅”的模式,其中每一个发送端知道多个可能的消息代理,而接收端只需把它们全都订阅即可。这个改动使得消息传输系统对于单点代理故障变得较为可靠。

消息自身是简单的键值对,它们自身可以轻松地进行扩展,并允许系统在不宕机的情况下进行升级。对于不兼容的改动,可以为新版本添加仅能被它使用的新属性(attribute),而同时允许旧版本在接受新消息时仍然能够工作。

服务不可用(Service unavailability)

无论什么时候,应用程序只要需要依赖某个服务来读取数据时,就应当可以在服务不可用时平滑地进行降级。

无论什么时候,只要数据写入到某个服务,这些数据应就当能够在接受服务不可用时进行缓冲。之后而当服务再次可用时,写入过程将自动传输写入请求。为了简单起见,Heroku 在发送数据之前,将多数服务直接进行了缓冲。该模式叫做写入失调(write de-syncronizing)。

有趣的是,Heroku 仍然在使用PostgreSQL作为中间缓冲,而没有使用他们自己的分布式存储Doozer。按照 Mark 的说法,这么做是因为他们非常了解 PostgreSQL 的局限性,并且在方面拥有不错的管理工具与经验,而这些在 Doozer 中都没有。正如 InfoQ 在 2011 年 11 月所报导的新闻,Heroku 将 PostgreSQL 作为服务提供给非 Heroku 应用程序。这也引发了演讲的第二个部分——社会技术方面。

社会技术(Socio-Technical)方面

让人机交互变得尽可能简单是一件头等大事。出现系统问题最常见的原因是由于人为的交互。在一个为改动设计的系统中,那些人为的交互毫无疑问包含了大量的改动。

部署和改版

借助自定义工具,Heroku 可以用一种增量模式进行部署。每一个部署会经历各种各样的阶段。与分离环境的传统阶段不同,这里的阶段是生产基础架构的子集,如“内部阶段”,“测试阶段”和“完整阶段”。新特性的改版遵循了同样的方式。使用这种方式可以将部署和特性改版相分离:首先完成新的部署,提供相同的功能,同时使用特性标记(feature flag)将新特性在背后隐藏。如果新特性证明没问题,那么特性会逐渐打开,从而可以更容易地定为问题所在。

可见性

监控是系统必不可少的一部分,尤其是对于具有多个变动部分的系统。Heroku 不断在监控和警报方面投入许多努力,因为它们的提供的可见性对于生产系统非常有价值。系统中的问题采用断言进行检测。下面是这些断言的一些例子:

  • 百分之 99 的延滞 < 50
  • 活动连接 > 10

Mark 给出的两个断言示例可以对当时可能发生的中断做出警告。

反馈级联

“下游组件影响所有调用它的部分”,是分布式系统中的一个典型问题。虽然架构方面已经借助平滑降级和写失调处理了不可用组件,然而还需避免过载子系统(overloading subsystem)。Heroku 针对这种情况采用了”流量控制“:特定的代码路径可以限制最大数量的调用次数,并且这些比率可以在运行时调整以适应改动过的代码或硬件。

查看英文原文:How Heroku Manages High Availability - QCon London Talk summary

Java云计算DevOps语言 & 开发架构