# 高可用与容灾原理

::: tip 前言
**系统挂了 1 分钟，可能意味着几十万的损失。** 高可用（High Availability）是指系统在面对硬件故障、软件 Bug、网络问题等异常情况时，仍能持续提供服务的能力。容灾（Disaster Recovery）则是在更大范围的灾难发生时，系统能够恢复服务的能力。
:::

**这篇文章会带你学什么？**

学完这章后，你将获得：

- **可用性度量**：理解"几个 9"的含义和对应的停机时间
- **故障转移**：掌握主备、主主、多活等高可用架构
- **容灾策略**：了解 RPO 和 RTO 的概念及设计方法
- **故障检测**：理解心跳、探针、熔断等故障发现机制
- **混沌工程**：了解如何主动注入故障来验证系统韧性

| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 可用性度量 | SLA、几个 9、停机时间 |
| **第 2 章** | 故障转移架构 | 主备、主主、多可用区、异地多活 |
| **第 3 章** | 容灾设计 | RPO、RTO、备份策略 |
| **第 4 章** | 故障检测与恢复 | 心跳、熔断、自动扩缩容 |
| **第 5 章** | 混沌工程 | 故障注入、韧性验证 |

---

## 1. 几个 9的定义与度量

可用性通常用"几个 9"来衡量，计算公式为：

**可用性 = 正常运行时间 / 总时间 × 100%**

例如一个月（30 天 = 43200 分钟）内停机了 43 分钟，可用性就是 (43200 - 43) / 43200 ≈ 99.9%。每多一个 9，允许的停机时间就少一个数量级，实现难度和成本也指数级增长。

| 可用性等级 | 百分比 | 每月允许停机 | 每年允许停机 | 典型要求 |
|-----------|--------|------------|------------|---------|
| 2 个 9 | 99% | 7.3 小时 | 3.65 天 | 内部工具 |
| 3 个 9 | 99.9% | 43 分钟 | 8.76 小时 | 普通业务系统 |
| 4 个 9 | 99.99% | 4.3 分钟 | 52.6 分钟 | 电商、SaaS |
| 5 个 9 | 99.999% | 26 秒 | 5.26 分钟 | 金融、支付 |

<AvailabilityCalculatorDemo />

::: tip SLA 是什么？
**SLA（Service Level Agreement，服务等级协议）** 是服务提供方与客户之间的正式承诺。比如 AWS S3 承诺 99.99% 的可用性，如果没达到，会按比例退款。SLA 不只是技术指标，更是商业合同——违反 SLA 意味着赔钱。
:::

::: tip 从 3 个 9 到 4 个 9 的鸿沟
3 个 9（99.9%）意味着每月可以停机 43 分钟——一次部署出问题，回滚一下就用完了。
4 个 9（99.99%）意味着每月只能停机 4 分钟——这要求你必须有自动故障转移、滚动部署、健康检查等完整的高可用体系。
:::

---

## 2. 故障转移架构

故障转移（Failover）是高可用的核心机制：当主节点故障时，自动切换到备用节点继续提供服务。

### 主备模式（Active-Standby）

最常见的高可用架构。主节点处理所有请求，备节点实时同步数据但不处理请求。主节点故障时，备节点自动接管。

```
正常状态：
  客户端 → 主节点（处理请求）
            备节点（同步数据，待命）

故障转移：
  客户端 → 备节点（接管为新主节点）
            原主节点（故障，等待修复）
```

关键问题是**脑裂（Split Brain）**：网络分区时，主备节点都认为对方挂了，同时对外提供服务，导致数据不一致。解决方案是引入**仲裁节点（Quorum）**——至少 3 个节点投票决定谁是主节点。

### 多可用区（Multi-AZ）

将服务部署在同一地域的多个数据中心（可用区）。单个数据中心断电、断网不影响整体服务。云厂商的可用区之间通常有低延迟专线连接（< 2ms）。

### 异地多活（Multi-Region Active-Active）

在不同城市甚至不同国家部署完整的服务副本，每个站点都能独立处理请求。这是最高级别的高可用架构，但也最复杂——核心挑战是**跨地域数据同步**的延迟和一致性问题。

<FailoverStrategyDemo />

| 架构 | 可用性级别 | 成本 | 复杂度 | 适用场景 |
|------|-----------|------|--------|---------|
| 单机 | 99%~99.9% | 低 | 低 | 开发测试、内部工具 |
| 主备 | 99.9%~99.99% | 中 | 中 | 中小型业务系统 |
| 多可用区 | 99.99% | 高 | 高 | 电商、SaaS 平台 |
| 异地多活 | 99.999% | 极高 | 极高 | 金融、大型互联网 |

---

## 3. 容灾设计：RPO 与 RTO

容灾设计围绕两个核心指标展开：

| 指标 | 全称 | 含义 | 举例 |
|------|------|------|------|
| RPO | Recovery Point Objective | 能容忍丢失多少数据 | RPO=0 表示不能丢任何数据 |
| RTO | Recovery Time Objective | 能容忍停机多长时间 | RTO=5min 表示 5 分钟内恢复 |

### 备份策略与 RPO 的关系

| 备份方式 | RPO | 成本 | 说明 |
|---------|-----|------|------|
| 每日全量备份 | 24 小时 | 低 | 最多丢一天数据 |
| 实时增量备份 | 分钟级 | 中 | binlog/WAL 持续同步 |
| 同步复制 | 0 | 高 | 写入必须等副本确认 |

::: tip 不是所有数据都需要 RPO=0
用户头像丢了可以重新上传（RPO=24h 够了），但支付记录一条都不能丢（RPO=0）。根据数据的业务价值来决定备份策略，而不是一刀切。
:::

---

## 4. 故障检测与恢复

### 4.1 故障检测机制

| 机制 | 原理 | 检测速度 | 适用场景 |
|------|------|---------|---------|
| 心跳检测 | 定期发送心跳包，超时判定故障 | 秒级 | 节点存活检测 |
| 健康检查 | HTTP/TCP 探针检查服务状态 | 秒级 | 负载均衡器后端检测 |
| 业务探针 | 模拟真实请求检查业务逻辑 | 秒~分钟级 | 端到端可用性监控 |

**心跳检测的工作原理**：节点 A 每隔固定时间（如 5 秒）向监控方发送一个"我还活着"的信号。如果连续 N 次（如 3 次）没收到心跳，就判定节点 A 故障。关键参数是**心跳间隔**和**超时阈值**——间隔太短会增加网络开销，太长会延迟故障发现。

**健康检查的三种级别**：
- **存活探针（Liveness）**：进程还在运行吗？不在就重启
- **就绪探针（Readiness）**：服务能接受请求吗？不能就从负载均衡中摘除
- **启动探针（Startup）**：服务启动完成了吗？没完成就等待，不要误判为故障

### 4.2 自动恢复机制

| 机制 | 描述 | 典型工具 |
|------|------|---------|
| 自动重启 | 进程崩溃后自动拉起 | systemd、PM2、K8s |
| 自动扩缩容 | 负载升高时自动增加实例 | K8s HPA、云厂商 Auto Scaling |
| 熔断降级 | 下游故障时快速失败，防止级联故障 | Hystrix、Sentinel、Resilience4j |
| 限流 | 超过容量的请求直接拒绝 | Nginx limit_req、网关限流 |

**熔断器模式（Circuit Breaker）详解**：

熔断器的灵感来自电路中的保险丝——当电流过大时自动断开，保护整个电路不被烧毁。在微服务中，当下游服务故障时，熔断器会"断开"，让请求快速失败，而不是傻等超时。

```
熔断器三种状态：

  关闭（正常）──→ 失败率超过阈值 ──→ 打开（熔断）
       ↑                                    │
       │                              等待冷却时间
       │                                    ↓
       └── 探测请求成功 ←── 半开（试探）
```

- **关闭状态**：正常转发请求，同时统计失败率
- **打开状态**：所有请求直接返回错误（快速失败），不再调用下游
- **半开状态**：冷却时间到后，放行少量探测请求。如果成功，恢复关闭；如果失败，继续打开

**降级（Fallback）** 是熔断的配套策略：熔断触发后，不是直接报错，而是返回一个"兜底"结果。比如推荐服务挂了，就返回热门商品列表；用户头像加载失败，就显示默认头像。

---

## 5. 混沌工程：主动找问题

混沌工程的核心理念是：**与其等故障发生，不如主动制造故障**，在可控环境中验证系统的韧性。

| 工具 | 提出者 | 核心能力 |
|------|--------|---------|
| Chaos Monkey | Netflix | 随机终止生产环境的实例 |
| Chaos Mesh | PingCAP | K8s 环境下的故障注入 |
| Litmus | CNCF | 云原生混沌工程框架 |
| ChaosBlade | 阿里巴巴 | 多场景故障注入工具 |

::: tip 混沌工程的实施步骤
1. **定义稳态**：明确系统正常运行的指标（如 P99 延迟 < 200ms）
2. **提出假设**：如果某个节点挂了，系统应该在 30 秒内自动恢复
3. **注入故障**：在可控范围内制造故障（先在测试环境，再到生产）
4. **观察结果**：系统是否如预期恢复？有没有级联故障？
5. **修复弱点**：发现问题后改进架构和流程
:::

---

## 总结

高可用不是一个功能，而是一种架构能力。它需要从设计、开发、部署、运维的每个环节去保障。

回顾本章的关键要点：

1. **几个 9**：每多一个 9，停机时间少一个数量级，成本和复杂度指数增长
2. **故障转移**：从主备到异地多活，根据业务需求选择合适的架构
3. **RPO 与 RTO**：根据数据价值和业务容忍度设计备份和恢复策略
4. **自动化**：故障检测、自动重启、熔断降级是高可用的基础设施
5. **混沌工程**：主动制造故障，在可控环境中验证系统韧性

## 延伸阅读

- [Site Reliability Engineering](https://sre.google/sre-book/table-of-contents/) - Google SRE 经典
- [Chaos Monkey](https://netflix.github.io/chaosmonkey/) - Netflix 混沌工程工具
- [Release It!](https://pragprog.com/titles/mnee2/release-it-second-edition/) - 生产环境设计模式
- [Chaos Mesh](https://chaos-mesh.org/) - K8s 混沌工程平台

