跳转至

稳定性保障 (Reliability Engineering)

一句话概述

广告系统的稳定性直接关系到收入,每分钟宕机都意味着真金白银的损失,需要通过限流、熔断、降级、灰度发布、容灾等手段构建多层防护体系,目标是 99.99% 可用性。


稳定性目标

可用性目标:
  99.9%  → 每年宕机 8.76 小时
  99.99% → 每年宕机 52.6 分钟 ← 广告系统目标
  99.999% → 每年宕机 5.26 分钟

收入影响估算:
  日广告收入: ¥1000 万
  每分钟收入: ¥6,944
  宕机 1 小时: 损失 ¥41.7 万

限流 (Rate Limiting)

限流策略

策略 说明 适用场景
固定窗口 每秒/每分钟固定请求数 简单限流
滑动窗口 滑动时间窗口内的请求数 精确限流
令牌桶 固定速率生成令牌,请求消耗令牌 允许突发
漏桶 固定速率处理请求 平滑流量

限流维度

多维度限流:
  - 全局 QPS 限流: 系统总 QPS 上限
  - 广告主限流: 单个广告主的请求频率
  - IP 限流: 单个 IP 的请求频率
  - 接口限流: 单个 API 的 QPS 上限
  - 自适应限流: 根据系统负载动态调整

自适应限流:
  CPU > 80% → 开始限流
  CPU > 90% → 加大限流力度
  CPU < 70% → 恢复正常

熔断 (Circuit Breaker)

熔断器状态机

stateDiagram-v2
    [*] --> Closed
    Closed --> Open : 错误率 > 阈值
    Open --> HalfOpen : 超时后试探
    HalfOpen --> Closed : 试探成功
    HalfOpen --> Open : 试探失败
    state Closed {
        [*] : 正常通过请求
    }
    state Open {
        [*] : 快速失败
    }
    state HalfOpen {
        [*] : 试探请求
    }

熔断配置示例

下游服务熔断配置:
  特征服务:
    错误率阈值: 50%
    统计窗口: 10秒
    最小请求数: 20
    熔断时长: 30秒
    降级策略: 使用默认特征值

  排序服务:
    错误率阈值: 30%
    统计窗口: 5秒
    熔断时长: 15秒
    降级策略: 使用粗排结果

降级 (Degradation)

降级策略分级

Level 0: 正常服务
  所有功能正常运行

Level 1: 轻度降级
  - 关闭非核心特征 (如实时特征)
  - 减少召回路数
  - 降低模型复杂度

Level 2: 中度降级
  - 跳过精排,使用粗排
  - 关闭个性化,使用热门广告
  - 减少广告候选数

Level 3: 重度降级
  - 返回缓存的广告结果
  - 只返回品牌广告 (预加载)
  - 减少广告位数量

Level 4: 极端降级
  - 返回空广告
  - 保护系统不崩溃

自动降级触发

触发条件 → 降级动作:
  CPU > 85%        → Level 1
  P99 延迟 > 150ms → Level 1
  CPU > 95%        → Level 2
  P99 延迟 > 300ms → Level 2
  错误率 > 5%      → Level 2
  下游服务不可用    → Level 3
  数据库不可用      → Level 4

灰度发布 (Canary Release)

发布流程

flowchart TD
    A[代码变更] --> B[预发布环境<br/>功能验证]
    B --> C[灰度 1%<br/>观察 30 分钟]
    C -->|指标正常| D[灰度 10%<br/>观察 1 小时]
    D -->|指标正常| E[灰度 50%<br/>观察 2 小时]
    E -->|指标正常| F[全量 100%]
    C -->|异常| G[自动回滚]
    D -->|异常| G
    E -->|异常| G

蓝绿部署

flowchart LR
    A["蓝色环境 v1.0<br/>100% 流量"] -->|部署新版本| B["绿色环境 v1.1<br/>0% 流量"]
    B -->|验证通过| C["切换流量到绿色<br/>蓝色变备用"]
    C -->|异常| D[秒级切回蓝色]

容灾 (Disaster Recovery)

多机房容灾

flowchart LR
    subgraph 同城双活
        A1["机房 A (50%流量)"] <-->|同步| A2["机房 B (50%流量)"]
    end

单机房故障 → 另一机房承接 100% 流量

flowchart LR
    subgraph 异地灾备
        B1["上海 主 (100%流量)"] -->|异步复制| B2["北京 备 (0%流量)"]
    end

主机房故障 → DNS 切换到备机房 (分钟级)

数据容灾

Redis:
  - 主从复制 + 哨兵
  - Redis Cluster 多副本
  - 跨机房异步复制

Kafka:
  - 多副本 (replica=3)
  - ISR 机制保证数据不丢
  - MirrorMaker 跨机房同步

HDFS:
  - 3 副本存储
  - 跨机架分布
  - NameNode HA

监控告警体系

监控层次

flowchart TD
    A["业务监控<br/>收入、CTR、CVR、广告主数、填充率"]
    B["应用监控<br/>QPS、延迟、错误率、成功率"]
    C["中间件监控<br/>Kafka Lag、Redis 延迟、DB 连接数"]
    D["基础设施监控<br/>CPU、内存、磁盘、网络"]
    A --- B --- C --- D

告警分级

级别 说明 响应时间 示例
P0 系统不可用 5 分钟 全量服务宕机
P1 严重影响 15 分钟 收入下降 >20%、延迟翻倍
P2 明显影响 1 小时 部分功能异常、指标下降
P3 轻微影响 4 小时 非核心功能异常

监控工具链

指标采集: Prometheus / OpenTelemetry
指标存储: Prometheus / VictoriaMetrics / InfluxDB
可视化:   Grafana
告警:     Alertmanager / PagerDuty
链路追踪: Jaeger / Zipkin / SkyWalking
日志:     ELK (Elasticsearch + Logstash + Kibana)

故障应急

应急流程

1. 发现 (Detection)
   - 监控告警触发
   - 用户/客户反馈
   - 值班人员巡检

2. 响应 (Response)
   - 确认故障范围和影响
   - 拉起应急群/电话会议
   - 通知相关方

3. 止血 (Mitigation)
   - 回滚变更
   - 切换流量
   - 降级/限流
   - 目标: 最短时间恢复服务

4. 恢复 (Recovery)
   - 定位根因
   - 修复问题
   - 验证恢复

5. 复盘 (Post-mortem)
   - 时间线梳理
   - 根因分析 (5 Why)
   - 改进措施
   - 文档归档

常见故障场景与应对

故障 影响 应对
服务 OOM 部分实例不可用 自动重启 + 扩容
Redis 故障 特征/频控不可用 降级到默认值
模型加载失败 排序异常 回滚到上一版本模型
Kafka 积压 实时数据延迟 扩容消费者 + 降级
数据库慢查询 报表/API 超时 限流 + 缓存
网络抖动 服务间调用失败 重试 + 熔断
流量突增 系统过载 自动扩容 + 限流

变更管理

变更风险控制

变更分级:
  S 级: 核心投放链路变更 → 需要审批 + 灰度
  A 级: 重要功能变更 → 需要 Code Review + 灰度
  B 级: 非核心变更 → Code Review
  C 级: 配置变更 → 自助变更 + 记录

变更窗口:
  禁止变更时段: 大促期间、节假日
  推荐变更时段: 工作日 10:00-16:00
  紧急变更: 需要审批 + 值班人员在线

与大数据开发的关联

  • 数据管道监控: Kafka/Flink/Spark 任务的监控和告警
  • 数据质量告警: 数据量异常、延迟异常的检测
  • 故障排查: 数据链路问题的快速定位
  • 容灾演练: 数据系统的容灾切换演练
  • 变更管理: 数据任务变更的风险控制

面试高频问题

  1. 限流、熔断、降级分别是什么?各自的应用场景?
  2. 灰度发布的流程是怎样的?
  3. 广告系统如何做到 99.99% 可用性?
  4. 多机房容灾的方案有哪些?
  5. 线上故障的应急处理流程?

推荐阅读

  • 《SRE: Google 运维解密》
  • 《Release It! 软件设计与部署》
  • Netflix Hystrix — 熔断器
  • Sentinel — 阿里限流熔断