# 高可用與容災原理

::: 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 混沌工程平台
