跳转至

🛡️ 高可用与容灾

学习时间: 5 小时 | 难度:⭐⭐⭐⭐ 进阶 | 前置知识: 04-分布式系统基础

📌 教学边界:本章中的 SLA、RPO/RTO、熔断阈值和多活距离只适合作为讨论框架或一阶估算。真实生产目标必须由历史可用性、故障域独立性、切换演练、链路依赖和合规要求共同决定。


🎯 本章目标

  • 理解高可用架构的核心模式
  • 掌握故障检测与自动转移机制
  • 深入理解熔断器、限流、降级策略
  • 了解多活架构的设计原则与实践
  • 掌握灾备方案设计和 SLA 计算

📋 目录


1. 高可用模式

1.1 高可用的定义

高可用( High Availability, HA )是指系统在一定时间内保持正常运行的能力。

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

"几个9"的含义:
  99%     = 2个9 = 每年停机 3.65天
  99.9%   = 3个9 = 每年停机 8.76小时
  99.99%  = 4个9 = 每年停机 52.6分钟
  99.999% = 5个9 = 每年停机 5.26分钟

1.2 主从模式( Active-Standby )

Text Only
正常状态:                      故障转移后:
┌──────────┐                  ┌──────────┐
│  Master  │ ← 处理所有请求    │  Master  │ ← 故障!
│ (Active) │                  │ (Down)   │
└────┬─────┘                  └──────────┘
     │ 同步
┌────▼─────┐                  ┌──────────┐
│  Slave   │ ← 待命           │  Slave   │ ← 提升为Master
│(Standby) │                  │(→Active) │    接管所有请求
└──────────┘                  └──────────┘
优势 劣势
实现简单 资源利用率 50%(备机闲置)
故障切换快 切换期间有短暂中断
数据一致性好保证 只有一倍冗余

1.3 主主模式( Active-Active / Dual Master )

Text Only
┌──────────┐   双向同步   ┌──────────┐
│ Master A │ ←─────────→ │ Master B │
│ (Active) │              │ (Active) │
└────┬─────┘              └────┬─────┘
     │                         │
     ▼                         ▼
  处理写请求              处理写请求
  (region_A的用户)        (region_B的用户)
优势 劣势
资源利用率 100% 数据冲突问题
负载分担 双向同步复杂
某节点故障另一个接管 需要冲突解决方案

冲突解决策略

策略 说明 适用
最后写入胜出( LWW ) 以时间戳较新的为准 简单场景
业务规则 根据业务逻辑合并 复杂场景
分区避免 不同 Master 写不同数据 用户维度分区
人工介入 冲突时告警人工处理 关键数据

1.4 集群模式

Text Only
无主集群(如Cassandra):

  ┌───┐  ┌───┐  ┌───┐
  │N1 │──│N2 │──│N3 │
  └─┬─┘  └─┬─┘  └─┬─┘
    │      │      │
  ┌─┴─┐  ┌─┴─┐  ┌─┴─┐
  │N4 │──│N5 │──│N6 │
  └───┘  └───┘  └───┘

  所有节点对等,无Leader
  写入时写W个节点,读取时读R个节点
  W + R > N 保证一致性

有主集群(如Redis Cluster):

  ┌──────────┐  ┌──────────┐  ┌──────────┐
  │ Master 1 │  │ Master 2 │  │ Master 3 │
  │ slot 0-  │  │slot 5461-│  │slot 10923│
  │  5460    │  │  10922   │  │  -16383  │
  └────┬─────┘  └────┬─────┘  └────┬─────┘
       │              │              │
  ┌────▼─────┐  ┌────▼─────┐  ┌────▼─────┐
  │ Slave 1  │  │ Slave 2  │  │ Slave 3  │
  └──────────┘  └──────────┘  └──────────┘

1.5 模式对比

模式 可用性 资源利用 复杂度 一致性 适用场景
主从 较高 50% 左右 取决复制模式与切换策略 数据库、缓存
主主 较高到很高 100% 需要显式处理冲突 多地域部署
集群 取决副本与故障域设计 较高 很高 可配置 大规模系统

2. 故障检测与转移

2.1 心跳检测

Text Only
心跳机制:
  节点定期发送心跳消息("我还活着")
  超过阈值未收到心跳 → 判定故障

  Node A → ♥ → ♥ → ♥ → ♥ → ✗ → ✗ → ✗ → 判定Node A故障
                          超过N次未收到心跳

心跳参数设计:
  心跳间隔: 1-5秒(太短增加网络开销,太长检测慢)
  超时阈值: 3-5次心跳间隔

  示例:心跳间隔2秒,3次超时
  最快检测时间: 4秒
  最慢检测时间: 6秒

2.2 Gossip 协议

Text Only
Gossip(流言)协议:
  节点随机选择其他节点交换信息
  类似于流言传播

  Round 1:                Round 2:
  A知道B故障               A告诉C: "B故障了"
  A随机选C通知             D告诉E: "听说B故障了"

  Round 3:                Round N:
  C告诉D: "B故障了"        所有节点都知道B故障了
  E告诉F: "B故障了"

  传播速度: O(logN) 轮,N个节点

优势:
  - 去中心化,无SPOF
  - 最终收敛
  - 容忍网络分区

劣势:
  - 检测速度不如心跳快
  - 信息传播有延迟

使用Gossip的系统:
  - Redis Cluster
  - Cassandra
  - Consul(Serf)

2.3 φ(Phi) Accrual 故障检测

Text Only
传统检测:二值判断(活着 or 死了)
Phi检测:输出一个怀疑程度(0~∞)

  φ值  │
  10   │                ╱──── 几乎确定故障
       │              ╱
   5   │            ╱
       │          ╱
   1   │      ╱──── 开始怀疑
       │    ╱
   0   │──╱────────── 正常
       └──────────────────→ 心跳延迟

  φ > 阈值(如8) → 判定故障

优势:自适应不同网络延迟
使用:Cassandra、Akka

2.4 故障转移流程

Text Only
完整的故障转移(Failover)流程:

1. 故障检测
   ├── 心跳超时
   ├── 健康检查失败
   └── 多个监控节点确认

2. 确认故障(防止误判)
   ├── 多次重试
   ├── 多个检测源确认
   └── 排除网络分区

3. 选举新Leader
   ├── 数据最新的从节点
   ├── 优先级最高的
   └── Raft/Paxos选举

4. 切换流量
   ├── DNS切换(分钟级)
   ├── VIP漂移(秒级)
   ├── LB配置更新(秒级)
   └── Service Discovery更新(秒级)

5. 数据恢复
   ├── 检查数据一致性
   ├── 修复可能的数据丢失
   └── 补发丢失的消息

6. 原节点恢复
   ├── 作为新的从节点加入
   └── 同步数据

3. 熔断器

3.1 熔断器模式

Text Only
没有熔断器:                      有熔断器:
Service A → Service B(故障)       Service A → 熔断器 → Service B(故障)
         ← 超时(30s)                        ← 快速失败(5ms)
Service A → Service B(故障)
         ← 超时(30s)              熔断器检测到B连续失败
...                               → 断开电路
请求堆积、A也变慢                  → 后续请求直接返回降级结果
→ 级联故障!                      → 定期探测B是否恢复

熔断器就像电路中的保险丝:
  检测到下游异常 → 切断连接 → 保护上游不被拖垮

3.2 熔断器状态机

Text Only
┌──────────┐     连续失败       ┌──────────┐
│  Closed  │  达到阈值(如50%)   │   Open   │
│  (关闭)  │ ──────────────→   │  (打开)  │
│ 正常放行 │                   │ 快速失败  │
└──────────┘                   └────┬─────┘
     ▲                              │
     │                         超时后(如30s)
     │  探测请求成功                  │
     │                              ▼
     │                        ┌──────────┐
     └─────────────────────── │Half Open │
                  恢复        │ (半开)   │
                              │ 放行少量 │
                              │ 探测请求 │
                              └──────────┘
                              探测失败 │
                              回到Open

状态说明

状态 行为 转移条件
Closed (关闭) 正常放行所有请求 失败率超阈值 → Open
Open (打开) 快速拒绝所有请求 等待超时 → Half-Open
Half-Open (半开) 放行少量探测请求 成功 → Closed / 失败 → Open

3.3 熔断器框架对比

特性 Hystrix Sentinel Resilience4j
开发商 Netflix(已停更) Alibaba 社区
熔断
限流 ✅(强项)
降级
热点限流
系统保护 ✅( CPU/Load )
控制台 Dashboard Dashboard (丰富) Grafana
响应式 RxJava ✅ 原生支持
适用 历史项目 国内/阿里云 Spring Boot

3.4 熔断器实现

Python
import time
import threading  # 线程池/多线程:并发执行任务
from enum import Enum

class CircuitState(Enum):
    CLOSED = "closed"
    OPEN = "open"
    HALF_OPEN = "half_open"

class CircuitBreaker:
    """熔断器:当下游服务连续失败时自动断开,避免级联故障"""
    def __init__(self, failure_threshold=5, recovery_timeout=30,
                 half_open_max_calls=3):
        self.failure_threshold = failure_threshold  # 触发熔断的连续失败次数
        self.recovery_timeout = recovery_timeout    # Open状态持续时间(秒),之后进入Half-Open
        self.half_open_max_calls = half_open_max_calls  # 半开状态最多放行的探测请求数

        self.state = CircuitState.CLOSED   # 初始状态:关闭(正常放行)
        self.failure_count = 0             # 当前连续失败计数
        self.success_count = 0             # 半开状态下的成功计数
        self.last_failure_time = None      # 最后一次失败的时间戳
        self.half_open_calls = 0           # 半开状态已放行的请求数
        self.lock = threading.Lock()       # 线程锁,保证状态转换的原子性

    def call(self, func, *args, **kwargs):  # *args接收任意位置参数;**kwargs接收任意关键字参数
        """通过熔断器调用函数:根据当前状态决定放行或快速失败"""
        with self.lock:
            if self.state == CircuitState.OPEN:
                # Open状态:检查是否到了尝试恢复的时间
                if self._should_try_reset():
                    self.state = CircuitState.HALF_OPEN  # 进入半开状态,允许少量探测
                    self.half_open_calls = 0
                else:
                    raise CircuitBreakerOpenError("Circuit breaker is OPEN")  # 直接快速失败

            if self.state == CircuitState.HALF_OPEN:
                # 半开状态:限制探测请求数量
                if self.half_open_calls >= self.half_open_max_calls:
                    raise CircuitBreakerOpenError("Half-open call limit reached")
                self.half_open_calls += 1

        try:  # try/except捕获异常
            result = func(*args, **kwargs)
            self._on_success()
            return result
        except Exception as e:
            self._on_failure()
            raise

    def _on_success(self):
        """调用成功时的处理"""
        with self.lock:
            if self.state == CircuitState.HALF_OPEN:
                self.success_count += 1
                # 半开状态下连续成功达标 → 恢复为关闭状态
                if self.success_count >= self.half_open_max_calls:
                    self.state = CircuitState.CLOSED
                    self._reset_counts()
            elif self.state == CircuitState.CLOSED:
                self._reset_counts()  # 关闭状态下成功则重置失败计数

    def _on_failure(self):
        """调用失败时的处理"""
        with self.lock:
            self.failure_count += 1
            self.last_failure_time = time.time()

            if self.state == CircuitState.HALF_OPEN:
                self.state = CircuitState.OPEN  # 半开状态下失败 → 重新打开熔断器
            elif self.failure_count >= self.failure_threshold:
                self.state = CircuitState.OPEN  # 失败次数达到阈值 → 触发熔断

    def _should_try_reset(self):
        """判断Open状态是否已超时,可以尝试Half-Open恢复"""
        return (time.time() - self.last_failure_time) >= self.recovery_timeout

    def _reset_counts(self):
        """重置所有计数器"""
        self.failure_count = 0
        self.success_count = 0

class CircuitBreakerOpenError(Exception):
    pass
Java
// Java使用Resilience4j实现熔断器
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;

// 配置熔断器参数
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
    .failureRateThreshold(50)           // 失败率超过50%触发熔断
    .waitDurationInOpenState(Duration.ofSeconds(30))  // 熔断后等待30秒再尝试恢复
    .slidingWindowSize(10)              // 用最近10次调用统计失败率
    .minimumNumberOfCalls(5)            // 至少5次调用后才开始计算失败率
    .build();

// 创建名为"myService"的熔断器实例
CircuitBreaker breaker = CircuitBreaker.of("myService", config);

// 使用熔断器包装远程调用,失败时自动触发熔断保护
String result = breaker.executeSupplier(() -> {
    return remoteService.call();
});

4. 限流与降级策略

4.1 限流策略

维度 说明 示例
接口级 限制单个接口 QPS /API/order 限制 1000 QPS
用户级 限制单个用户请求频率 每用户 100 次/分钟
IP 级 限制单个 IP 请求数 每 IP 50 次/秒
全局级 限制整个系统 QPS 系统总 QPS ≤ 10000
热点级 限制热点参数 商品 ID=12345 限制 100/秒

4.2 降级策略

Text Only
降级 = 当系统超负荷时,主动关闭一些非核心功能

降级级别:
  Level 0(正常):所有功能正常
  Level 1(轻度):关闭推荐、广告等非核心功能
  Level 2(中度):关闭评论、点赞等次要功能
  Level 3(重度):只保留核心功能(如下单、支付)
  Level 4(极端):只读模式,停止写入

降级方式:
┌─────────────────────────────────────────────┐
│ 手动降级:运维人员通过开关控制                   │
│   配置中心 → 修改开关 → 服务读取 → 降级生效     │
│                                              │
│ 自动降级:系统根据指标自动触发                   │
│   监控指标 → 超过阈值 → 自动触发 → 降级生效     │
│                                              │
│ 降级返回:                                    │
│   - 返回默认值/兜底数据                        │
│   - 返回缓存的旧数据                          │
│   - 返回简化版本的结果                         │
│   - 返回友好的错误提示                         │
└─────────────────────────────────────────────┘

4.3 限流、熔断、降级的区别

维度 限流 熔断 降级
触发 请求量超过阈值 下游失败率过高 系统负载过高
目的 保护自身不被压垮 保护自身不被下游拖垮 保证核心可用
对象 入站流量 出站调用 系统整体
粒度 请求级 服务级 功能级
处理 拒绝/排队 快速失败/fallback 关闭/简化功能
比喻 高速收费站控流 电路保险丝 战略性撤退

5. 多活架构

5.1 多活架构概述

Text Only
单机房部署:                    多活部署:
  ┌──────┐                    ┌──────┐    ┌──────┐
  │机房A │                    │机房A │    │机房B │
  │全部  │                    │服务  │    │服务  │
  │服务  │                    │数据  │ ⟷  │数据  │
  └──────┘                    └──────┘    └──────┘

  风险:机房故障 = 全网故障     优势:一个机房故障,另一个接管

5.2 同城双活

Text Only
同城双活架构:

     用户流量
  ┌────▼────┐
  │  DNS/LB │ ← 流量分发
  └──┬───┬──┘
     │   │
     ▼   ▼
  ┌─────┐ ┌─────┐
  │机房A│ │机房B│  ← 同城(网络延迟 < 2ms)
  │     │ │     │
  │ App │ │ App │  ← 双活,都处理流量
  │     │ │     │
  │ DB  │ │ DB  │  ← 一主一从 或 双主
  │(主) │ │(从) │
  └──┬──┘ └──┬──┘
     │       │
     └───┬───┘
         │ 同步复制(低延迟)

特点:
  - 两个机房都处理读流量
  - 写流量通常指向主库所在机房
  - 网络延迟低,具备采用更强复制策略的可能
  - 但是否能同步复制、是否值得同步复制,仍取决于链路抖动、quorum 与业务写延迟预算

5.3 异地多活

Text Only
异地多活架构(如北京-上海-广州三地):

     北京用户         上海用户         广州用户
       │               │               │
  ┌────▼────┐    ┌─────▼────┐    ┌────▼────┐
  │ 北京机房 │    │ 上海机房  │    │ 广州机房 │
  │         │    │          │    │         │
  │ App     │    │ App      │    │ App     │
  │ Cache   │    │ Cache    │    │ Cache   │
  │ DB(主)  │    │ DB(主)   │    │ DB(主)  │
  └────┬────┘    └────┬─────┘    └────┬────┘
       │              │              │
       └──────────────┼──────────────┘
              异步数据同步
              延迟: 30-100ms

异地多活核心挑战

挑战 说明 解决方案
数据同步延迟 跨城市网络延迟 30-100ms 异步同步 + 最终一致
数据冲突 多地同时写入同一数据 用户维度路由(同一用户只在一地写)
流量路由 如何将用户分配到正确的机房 按地域/userID 路由
切换成本 故障时切换流量 DNS 切换 + 预案演练
数据一致性 多地数据如何保持一致 单元化 + 全局数据中心

单元化架构

Text Only
单元化 = 将系统按用户维度拆分为独立的单元

  用户 → 路由规则(如userID % 3)→ 分配到对应单元

  ┌──────────── 北京单元 ──────────┐
  │  用户 0,3,6,9,...              │
  │  ┌─────┐ ┌─────┐ ┌─────┐    │
  │  │ App │ │Cache│ │ DB  │    │
  │  └─────┘ └─────┘ └─────┘    │
  └────────────────────────────────┘

  ┌──────────── 上海单元 ──────────┐
  │  用户 1,4,7,10,...             │
  │  ┌─────┐ ┌─────┐ ┌─────┐    │
  │  │ App │ │Cache│ │ DB  │    │
  │  └─────┘ └─────┘ └─────┘    │
  └────────────────────────────────┘

  ┌──────────── 广州单元 ──────────┐
  │  用户 2,5,8,11,...             │
  │  ┌─────┐ ┌─────┐ ┌─────┐    │
  │  │ App │ │Cache│ │ DB  │    │
  │  └─────┘ └─────┘ └─────┘    │
  └────────────────────────────────┘

全局数据(如商品信息)→ 全局数据中心 → 同步到各单元

5.4 多活方案对比

方案 距离 延迟 数据一致性 复杂度 适用场景
同城双活 <50km <2ms 强一致可行 大部分业务
异地双活 100-2000km 30-100ms 最终一致 核心业务
异地多活 >1000km 50-300ms 最终一致 极高 超大型系统

6. 灾备方案

6.1 灾备级别

级别 名称 说明 RPO RTO 成本
冷备 Cold Standby 只有数据备份,需要时手动恢复 小时~天 小时~天
温备 Warm Standby 有备用环境但未运行,需启动 分钟~小时 分钟~小时
热备 Hot Standby 备用环境实时同步,随时切换 秒~分钟 秒~分钟
Text Only
RPO (Recovery Point Objective) = 能容忍丢失多少数据
  "数据库2小时前的备份" → RPO = 2小时

RTO (Recovery Time Objective) = 能容忍多长时间不可用
  "需要在30分钟内恢复" → RTO = 30分钟

RPO和RTO越小,成本越高!

          ▲ 成本
          │       ╱
          │      ╱
          │     ╱   RPO/RTO越小
          │    ╱    成本指数增长
          │   ╱
          │  ╱
          │ ╱
          └──────────────→ RPO/RTO
           大              小

6.2 备份策略

Text Only
数据备份方案:

1. 全量备份(Full Backup)
   每天凌晨备份全量数据
   优:恢复简单
   劣:耗时长、存储大

2. 增量备份(Incremental Backup)
   只备份上次之后变更的数据
   优:快速、存储小
   劣:恢复需要按顺序重放

3. 差异备份(Differential Backup)
   备份上次全量后所有变更
   优:恢复较简单
   劣:随时间增大

推荐策略:
  周日: 全量备份
  周一~周六: 增量备份

  恢复: 周日全量 + 后续增量按序重放

6.3 容灾演练

Text Only
混沌工程(Chaos Engineering):

原则:在生产环境中主动引入故障,验证系统弹性

Netflix Chaos Monkey:
  随机终止生产环境中的服务实例

故障注入类型:
  ├── 进程级:杀死服务进程
  ├── 网络级:模拟网络延迟/丢包/分区
  ├── 主机级:关闭服务器
  ├── 机房级:模拟机房故障
  └── 依赖级:模拟第三方服务不可用

演练流程:
  1. 定义稳态假设("系统在X故障下,核心功能不受影响")
  2. 设计实验(引入什么故障)
  3. 在小范围执行(先灰度)
  4. 观察结果
  5. 发现问题 → 修复 → 重新验证

7. SLA 计算

7.1 SLA 停机时间对照表

SLA 等级 可用性 年停机时间 月停机时间 周停机时间 适用场景
2 个 9 99% 3.65 天 7.31 小时 1.68 小时 内部系统
3 个 9 99.9% 8.76 小时 43.83 分钟 10.08 分钟 一般业务系统
3.5 个 9 99.95% 4.38 小时 21.92 分钟 5.04 分钟 重要业务系统
4 个 9 99.99% 52.60 分钟 4.38 分钟 1.01 分钟 核心业务系统
5 个 9 99.999% 5.26 分钟 26.30 秒 6.05 秒 金融/电信

7.2 串联系统 SLA 计算

Text Only
串联系统(所有组件都必须正常):

  A(99.9%) → B(99.9%) → C(99.9%)

  总SLA = 99.9% × 99.9% × 99.9% = 99.7%

  启示:组件越多,总体可用性越低!

  10个99.9%的组件串联 = 99.9%^10 = 99.0%
  只有2个9了!

7.3 并联系统 SLA 计算

Text Only
并联系统(冗余,任一组件正常即可):

  ┌─ A(99.9%) ─┐
  │             │
  ├─ B(99.9%) ─┤
  │             │
  └─ C(99.9%) ─┘

  不可用概率 = (1-99.9%)^3 = 0.001^3 = 0.000000001
  总SLA = 1 - 0.000000001 = 99.9999999% ≈ 9个9

  2个99.9%并联 = 1-(0.001)^2 = 99.9999% (6个9)
  3个99.9%并联 = 1-(0.001)^3 = 99.9999999% (9个9)

> ⚠️ **前提提醒**:上述并联公式默认故障相互独立,且流量、配置、网络、机房与上游依赖不会共同失效。真实系统里公共依赖、批量发布、配置错误和区域级事故会显著削弱理论上的并联收益。

7.4 混合系统 SLA 计算

Text Only
实际系统是串并联混合:

  ┌─ Web1 ─┐            ┌─ DB_Master ─┐
  ├─ Web2 ─┤ → Proxy → ├─ DB_Slave   ─┤ → Cache (99.99%)
  └─ Web3 ─┘            └──────────────┘

计算:
  Web层(并联): 1-(1-0.999)^3 = 99.9999999%
  Proxy(单点,但有备份): 99.99%
  DB层(主从): 1-(1-0.999)^2 = 99.9999%
  Cache: 99.99%

  总SLA = 99.9999999% × 99.99% × 99.9999% × 99.99%
        ≈ 99.98%
        ≈ 每年停机约1.75小时

  瓶颈分析:Proxy和Cache的单点是瓶颈!

7.5 提升 SLA 的方法

方法 效果 成本 适用
消除单点 显著提升 必做
增加冗余 显著提升 核心组件
故障自动切换 减少 RTO 生产环境
限流降级 保护核心功能 高流量场景
多活部署 极大提升 很高 核心业务
混沌工程演练 提前发现问题 成熟团队

8. 练习与延伸阅读

8.1 练习题

  1. SLA 计算: 一个系统包含: LB(99.99%) → 3 个 App 服务器(各 99.9%) → 缓存(99.95%) → 数据库主从(主 99.9%, 从 99.9%) 计算总体 SLA

    App 集群(3 个中至少 1 个可用): 1-(1-0.999)³ = 1-10⁻⁹ ≈ 99.9999999%。数据库主从(至少 1 个可用): 1-(1-0.999)² = 99.999999%。串联: 99.99% × 99.9999999% × 99.95% × 99.999999% ≈ 99.99% × 99.95% ≈ 99.94%。瓶颈在缓存层(99.95%)和 LB 层(99.99%)。

  2. 熔断器设计:为以下场景设计熔断参数:

  3. 支付服务调用银行接口( P99 延迟 500ms ,失败率通常<0.1%) > 可先以 超时 800ms、连续失败阈值 5 次、熔断 30s、半开 1 个探测请求 作为起步参数,再结合真实失败模式与人工回放校准。支付是核心链路,熔断后更常见的降级是"支付处理中"或转人工兜底。
  4. 推荐服务调用 ML 模型( P99 延迟 200ms ,失败率通常<1%) > 可先以 超时 300ms、失败率阈值 5%(10s 窗口)、熔断 10s、半开 3 个探测请求 作为示例起点;正式上线前应通过压测与灰度验证阈值是否合适。

  5. 多活方案:为一个 DAU 5000 万的电商系统设计同城双活方案

  6. 需要考虑:用户数据、订单数据、商品数据的同步策略
  7. 故障切换流程和时间目标

  8. 降级方案:为一个社交 APP 设计三级降级方案

  9. 列出核心功能和非核心功能
  10. 定义每个降级级别关闭的功能
  11. 设计降级触发条件

  12. 容灾演练:设计一个线上容灾演练方案

  13. 演练目标
  14. 故障注入方式
  15. 回滚方案
  16. 成功标准

8.2 延伸阅读

  • Netflix Hystrix Wiki — 熔断器设计原理
  • Alibaba Sentinel 官方文档 — 流量治理
  • Google SRE Book — 第 3,4 章 拥抱风险, SLO
  • Netflix: "Chaos Engineering — Netflix"
  • 阿里技术博客 — "异地多活设计 4 大原则"
  • 美团技术博客 — "美团外卖客户端高可用建设"

📝 本章小结

知识点 关键要点
高可用模式 主从(简单可靠)、主主(高利用率)、集群(高扩展)
故障检测 心跳(简单)、 Gossip(去中心化)、 Phi(自适应)
熔断器 Closed→Open→Half-Open 状态机,保护上游
限流降级 限流保护自身,降级保护核心功能
多活架构 同城双活(低延迟)、异地多活(高可用但复杂)
灾备 冷/温/热备, RPO 和 RTO 的权衡
SLA 串联会乘法下降,并联收益取决于故障独立性

上一章:分布式系统基础 | 下一章:经典系统设计案例

⚠️ 核验说明(2026-04-03):本页已完成逐段人工复核,重点修正了可用性模式、同城/异地多活、SLA 计算和熔断参数中的绝对化表述,并补充了这些结论都依赖故障独立性、切换流程和演练数据的前提。涉及具体云产品、多活复制能力或组织级 SLO 时,请以官方资料和运行实测为准。


最后更新日期: 2026-04-03