引子
来自这篇PPT: design-for-failure-is-key-to-success-in-the-cloud,是我搜索“design for failure”时前3的页面。它简明的讲解了什么是“拥抱失败的设计原则”。
以下是该PPT的简要总结。
Traditional (non-cloud) model, 设计时需要考虑:
- design for non-failure: 需要高效可靠的硬件与软件
- 应用冗余/备份 部署: 需要额外的资源
- 高效的管理能力: 需要专人、专职管理
而cloud modle 设计是: design for failure:
- assume nothing: 不做任何前提性假设
- expect failure: 任何地方、任何时间都可能出错;现在可用,不代表之后也可用
- embrace failure, make it a first class citizen
- 需要 handle ALL failures:
- design for redundancy
- 评估每个点的failure;
- 分布式架构;
- 最小化状态(to be stateless)
- monitor extensively
- 自己report health
- 外部监控接口
- load 和lantency的监控
- 保护性的重启组件(类似 熔断与降级)
- track dependencies
- 识别所有的外部依赖:硬件,第三方库,网络,服务,自己的其他组件等
- 跟踪外部依赖的可用性
思考
伴随着AWS Cloud的流行,该理念大约与2011后开始兴起。假如在一个未知的云环境中,认为万事万物(包括自己)挂掉确实是合情合理的。
那么问题是,在我们自己的应用做架构设计时,将该理念提升为核心设计准则是否合适?
我认为,有必要。先从收益和付出的角度来看,要实现该理念,需要的只是抛开某些前提条件后,新增的工作的内容和需求。
也就是说,实现该理念,需要增加软件支出(复杂度、人力、软件周期等),收益是自身应用的可靠性。相比较而言是划算的。
其次,从我的实际经验来看,通常假设“Always On”的各种组件都曾挂过。比如,HBase、Zookeeper、MySQL、Gitlab Server、 包括网络,都曾出现过各种问题。
因此,增强应用自身容错的健壮性是极有必要的。(只有半夜被电话叫醒的人才能真的懂)
但是,该理念说起来容易,做起来难。首先,应用分布式架构,且最好实现成无状态的,就又涉及到如何将业务做到分布式一致性的问题。(那又是另一个话题了)再者,为了做自身的监控,又会侵入业务逻辑,增加额外的操作与复杂度。这里我仅提一点,想要做到监控的数据准确且完备,就是个劳心劳力的长期工作。最后,要识别出所有的外部依赖,并处理相应可能的错误,对具体项目参与者(包括leader和programmer)都有很高的要求。这也就是所谓的“坑“,总要踩过之后,才知道疼。
Anyway,拥抱失败,处理失败,是架构设计中需要认真仔细考虑的重要一环。