稳定性保障 (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 任务的监控和告警
- 数据质量告警: 数据量异常、延迟异常的检测
- 故障排查: 数据链路问题的快速定位
- 容灾演练: 数据系统的容灾切换演练
- 变更管理: 数据任务变更的风险控制
面试高频问题¶
- 限流、熔断、降级分别是什么?各自的应用场景?
- 灰度发布的流程是怎样的?
- 广告系统如何做到 99.99% 可用性?
- 多机房容灾的方案有哪些?
- 线上故障的应急处理流程?
推荐阅读¶
- 《SRE: Google 运维解密》
- 《Release It! 软件设计与部署》
- Netflix Hystrix — 熔断器
- Sentinel — 阿里限流熔断