AWS 可靠性最佳实践:从架构设计到故障恢复一把梭
前言
酬勤, 每天一个啸知识.
最近帮一个客户复盘了一次生产故障,原因是某核心应用只部署在单可用区,结果遇到 AZ 级别的故障,直接导致服务中断了 2 个多小时。复盘会上大家面面相觑,但说实话这种问题真的太常见了------不是不知道要做高可用,而是"设计的时候觉得不会这么倒霉"、"后来资源紧张就拖着没改",然后就真的翻车了。
事后客户问我要不要搞个正式的架构评审,我说:"不如先从 AWS Well-Architected Framework 的可靠性支柱开始对齐,把方法论吃透了,自然就不会踩这些坑。"
AWS Well-Architected 框架的可靠性支柱,总结起来核心就五个字:设计即故障(aka: 墨菲定律) 😂 这不是悲观,而是承认"故障会发生",然后提前做好应对。
所以这篇文章,我打算从架构视角出发,结合我在 PaaS 平台上的实践经验,把 AWS 上构建高可用应用的关键设计原则掰开揉碎讲清楚,希望我的这些踩坑经历能帮大家少走弯路。
可靠性支柱到底是啥?
先来一个简明定义:
AWS Well-Architected Framework 的可靠性支柱,关注的是工作负载如何正确地、一致地执行其预期功能,并在中断时快速恢复。
说白了就这九字真言:不出事,出了能修,修得快。
整个支柱分为 5 个核心设计原则,我整理了一个表格方便对照:
| 设计原则 | 核心思想 | 一句话说人话 |
|---|---|---|
| 自动恢复 | 检测故障后自动修复/替换,无需人工介入 | 机器自己修自己,别等着运维被告警惊醒 |
| 水平扩展 | 通过增加实例数量来吸收流量波动,而非升级单体 | 扛不住了就加机器,扛得少就缩回去 |
| 冗余部署 | 跨多个可用区(AZ)甚至多区域(Region)部署 | 鸡蛋别放一个篮子里 |
| 可观察性 | 全面收集指标日志链路,快速定位异常 | 出了事你要能知道在哪、为什么 |
| 灾难恢复 | 定义 RTO/RPO,并演练备份/恢复流程 | 真到了救火的时候,有预案不乱 |
下面我逐一展开讲讲实战中的做法和踩过的坑。
1. 自动恢复:让机器学会"自愈"
自动恢复是最基础也是最重要的设计原则。它不是一个功能,而是一整套机制:
健康检查 + 自动替换
- ALB/NLB 健康检查:后端实例挂了 ALB/NLB 自动摘除,不转发流量。
- Auto Scaling 的自动替换:ASG 检测到 EC2 状态异常(如 StatusCheckFailed)后自动 terminate 重新拉起。
- 弹性伸缩策略:基于 CPU/Mem/请求数/队列数等指标的伸缩策略,让集群自动适应流量变化。
我之前的项目里,有个生产环境出现过一次 EC2 底层硬件故障,结果 ASG 自愈机制在 2 分钟内自动替换掉了故障实例,业务几乎无感。运维同学第二天看到 CloudWatch 告警历史才反应过来------这才是理想的自愈体验。
📝 Notes : 自动恢复的关键在于检测(这不又到我的监控老本行了嘛)。你需要在健康检查上定义合理的阈值,既不要太敏感(误报),也不要太迟钝(故障扩散)。一般建议设置 3 次连续的失败才标记为不健康。
2. 水平扩展:别再做"大就是好"这种蠢事
传统运维思维是"扛不住就升级配置"(垂直扩容),但云原生时代这玩意儿不香了。水平扩展的核心是:通过增加实例数量来分摊负载(水平扩容),而不是升级单实例规格。
具体做法:
- 使用 Auto Scaling Group 管理 EC2 实例池,定义最少/最多/期望实例数
- 基于 CloudWatch 指标(如 CPU > 70%、ALB 请求数 > 阈值)触发伸缩
- Scheduled Scaling:对已知流量高峰(如促销、季度末结算)提前扩容
- Predictive Scaling(基于 ML):帮你预测未来流量趋势,自动提前扩容
📌 示例:
某司一个承保系统,原来固定 3 台 c5.2xlarge 跑,每到月底就告警。后来改成 ASG + 基于 CPU 和请求数的伸缩策略,平时 3~4 台,月底自动扩到 8 台,之后缩回。成本没增加多少,但再也没有因为流量高峰出过告警。
3. 冗余部署:鸡蛋放 N 个篮子里
冗余部署的核心是消除单点故障(SPOF)。在 AWS 上,最基础的做法就是跨 AZ 部署。
多 AZ 部署的最佳实践
- 应用层:EC2/ECS/EKS 至少部署到 3 个可用区
- 数据层:RDS Multi-AZ(同步备用实例)、Aurora(跨 AZ 自动故障转移)
- 缓存层:ElastiCache 集群模式(跨 AZ 复制组)
- DNS 层:Route53 多值路由/故障转移路由
我见过一个经典的配置:某客户在单 AZ 部署了 OpenSearch 集群,结果 AZ 故障后数据丢失了 8 小时的数据。最后重建索引花了整整 3 天。这就是典型的省钱省出大麻烦。
📝 声明: 这里不是说一定要所有组件都跨 AZ。对于非关键组件(开发环境、内部工具),单 AZ 可以接受。但生产环境的核心业务,起码两 AZ 起步,强烈建议三 AZ。
关于 Route53 的"DNS 容错"
很多人容易忽略 DNS 层的容错设计。你可以通过 Route53 的多值路由(Multi-Value Answer Routing)或故障转移路由(Failover Routing)来实现跨 Region/跨 AZ 的自动切换。
比如基于 Route53 的健康检查,一旦某个 ALB 不可用,DNS 自动将流量导向备用 ALB。这玩意儿对读取类业务特别有用。
4. 可观察性:出事了你得知道在哪、为什么
没有可观察性,你连系统是不是正常都不知道,更别提自动恢复了。AWS 提供的主打工具是 CloudWatch + X-Ray。
CloudWatch
- Metrics:EC2/EBS/ALB/RDS 等核心指标全覆盖
- Logs:集中收集各类日志(应用日志、系统日志、VPC Flow Logs)
- Alarms:基于指标阈值触发告警,配合 SNS 发送通知
- Composite Alarms:多个条件组合判断,减少误报
X-Ray
- 服务映射:可视化应用的调用链
- 追踪分析:找出慢调用、错误调用、依赖关系
- 与 CloudWatch 联动:通过 X-Ray 追踪头信息定位具体问题
我个人最推荐的组合:CloudWatch 做指标告警 + X-Ray 做链路追踪 + CloudWatch Logs Insights 做日志分析。这样一旦告警触发,你可以一键跳到具体日志和时间段,快速定位根因。
当然, AWS 的这套比较贵, 替换为 Prometheus + 各种开源 Tracing (如 Jaeger, Zipkin 等) 可以更灵活地监控和分析。
5. 灾难恢复:别等出大事才后悔
灾难恢复(DR)是可靠性的最后一道防线。核心指标是 RTO(恢复时间目标) 和 RPO(恢复点目标)。
AWS 上常见的 DR 策略(从 RTO/RPO 长到短排序):
| 策略 | 描述 | 适用场景 |
|---|---|---|
| 备份 & 恢复 | 定期备份数据到 S3/Glacier,灾难时重新部署 | 开发/测试环境,成本优先 |
| Pilot Light | 启动一小部分核心服务做 DR,灾难时扩到全量 | 关键业务但预算有限 |
| Warm Standby | 启动一个缩小版的 DR 环境,可快速切换 | 核心生产业务 |
| Multi-Site Active/Active | 多 Region 同时提供服务,无切换时间 | 对高可用要求极高的业务(如金融交易) |
我比较推荐的做法是:至少做到 Warm Standby 级别。对于保险科技这样的行业,RTO 超过 30 分钟基本上就是不行的,RPO 最好控制在 5 分钟内。(当然, 代价是成本就上去了)
🤔 之前有朋友问我:这玩意儿不是有 Multi-AZ 就行了?干嘛搞 DR?
回答:Multi-AZ 解决的是 AZ 级别的故障,但遇到 Region 级别的问题(比如整个区域断网、自然灾害、美伊战争)你就抓瞎了。DR 就是为了应对这种极端情况。
写到这里,回头看看
AWS 可靠性设计,说到底就是一句话:承认故障会发生,提前准备好应对方案。
核心其实就那几件事:
- 自动恢复:用健康检查 + 自动替换让系统自愈
- 水平扩展:实例不够就加,多了就缩,别跟单机死磕
- 冗余部署:跨 AZ 部署,Route53 做 DNS 容错
- 可观察性:CloudWatch + X-Ray,出事能定位
- 灾难恢复:定义好 RTO/RPO,定期演练
技术迭代也好,架构重构也罢,不是一次到位,而是持续折腾、持续优化。希望我的这些经验能帮大家避开一些坑。如果大家有更好的实践,也欢迎找我聊聊。
酬勤, 每天一个啸知识. 你, 学废了吗?🤪