高可用实践
问题
如何保障系统高可用?故障演练怎么做?多活架构如何设计?
答案
高可用核心指标
| 可用性 | 年故障时间 | 说明 |
|---|---|---|
| 99% | 3.65 天 | 基础 |
| 99.9% | 8.76 小时 | 三个 9 |
| 99.95% | 4.38 小时 | 业界常见目标 |
| 99.99% | 52.6 分钟 | 四个 9 |
| 99.999% | 5.26 分钟 | 五个 9(极难) |
高可用架构 checklist
各层高可用方案
| 层级 | 方案 |
|---|---|
| 网关 | Nginx 主备 + Keepalived / 云 SLB |
| 应用 | 多实例部署 + K8s 自动重启 + HPA 弹性扩缩 |
| 数据库 | 主从复制 + 读写分离 + 故障自动切换(MHA / Orchestrator) |
| Redis | 哨兵 / Cluster + 持久化 |
| MQ | 多副本 + 同步刷盘 |
| 存储 | 多副本 + 跨区域备份 |
限流方案
Sentinel 限流
// 核心接口限流:QPS 超阈值直接拒绝
@SentinelResource(value = "createOrder", blockHandler = "createOrderBlockHandler")
public Result createOrder(OrderDTO dto) {
// 业务逻辑
}
public Result createOrderBlockHandler(OrderDTO dto, BlockException ex) {
return Result.fail("系统繁忙,请稍后再试");
}
Sentinel 限流规则
[
{
"resource": "createOrder",
"limitApp": "default",
"grade": 1, # QPS 模式
"count": 1000, # 阈值 1000 QPS
"strategy": 0,
"controlBehavior": 0 # 直接拒绝
}
]
故障演练(Chaos Engineering)
故障演练场景
1. 服务实例随机杀掉 → 验证自动重启和流量转移
2. 数据库主库宕机 → 验证自动主从切换
3. Redis 节点下线 → 验证哨兵切换和缓存降级
4. 网络延迟注入 → 验证超时设置和熔断
5. CPU / 内存打满 → 验证告警和弹性扩容
工具:
- ChaosBlade(阿里开源):支持 Java/K8s/Docker 故障注入
- Chaos Mesh:K8s 原生混沌工程平台
多活架构
| 类型 | 说明 | 复杂度 |
|---|---|---|
| 冷备 | 备机房不承担流量 | 低 |
| 同城双活 | 两个机房同时服务 | 中 |
| 异地多活 | 不同城市多个机房 | 极高 |
多活核心挑战:数据一致性,需要解决跨机房数据同步延迟问题。
SLA 保障体系
SLA 保障
1. 发布规范:灰度 → 观察 → 全量
2. 变更管控:非工作时间不变更,大促期间封网
3. 监控告警:核心指标 1 分钟内感知异常
4. 应急预案:每种故障场景有对应预案
5. 定期演练:每季度故障演练
6. 复盘改进:每次故障后复盘优化
常见面试问题
Q1: 你们系统如何保证高可用?
答案:
从四个维度回答:
- 冗余:服务多副本、数据库主从、多机房
- 容错:超时、熔断、降级、限流
- 监控:完善的监控 + 秒级告警 + 链路追踪
- 恢复:自动故障转移 + 快速回滚 + 应急预案
Q2: 如何做到 99.99% 可用性?
答案:
99.99% = 年故障时间 < 52 分钟,需要:
- 自动化故障检测和恢复(秒级感知、分钟级恢复)
- 多机房部署 + 自动切换
- 完善的监控告警体系
- 灰度发布 + Feature Flag
- 定期故障演练
Q3: 限流和熔断的区别?
答案:
- 限流:保护自己,限制入口流量不超过系统处理能力
- 熔断:保护自己,下游故障时快速失败不等待