高可用架构设计详细教程

高可用架构设计详细教程
高可用架构概述
高可用(High Availability, HA)架构设计是现代系统设计的核心要素之一。它旨在确保系统在面临硬件故障、网络问题、软件错误等异常情况时,仍能持续提供服务,将系统不可用时间降至最低。
什么是高可用?
高可用通常用可用性百分比来衡量:
| 可用性等级 | 年停机时间 | 说明 |
|---|---|---|
| 99%(两个 9) | 87.6 小时 | 基本可用 |
| 99.9%(三个 9) | 8.76 小时 | 商业级可用 |
| 99.99%(四个 9) | 52.6 分钟 | 高可用标准 |
| 99.999%(五个 9) | 5.26 分钟 | 电信级可用 |
为什么需要高可用?
- 业务连续性:系统停机意味着业务中断、收入损失
- 用户信任:频繁故障会导致用户流失
- 品牌声誉:不可用损害品牌形象
- 合规要求:金融行业等对可用性有严格要求
高可用设计原则
1. 冗余(Redundancy)
冗余是高可用的基石,通过增加备份组件来消除单点故障。
冗余级别:
应用层:多实例部署 + 负载均衡
数据库:主从复制 + 读写分离
缓存:集群部署 + 数据同步
网络:多链路 + 多运营商
机房:同城双活 + 异地灾备
冗余策略:
- N+1 冗余:N 个正常 + 1 个备用
- N+M 冗余:N 个正常 + M 个备用(M≥1)
- 2N 冗余:双倍容量,任意一台故障不影响服务
2. 故障转移(Failover)
当主节点故障时,系统自动切换到备用节点,确保服务不中断。
故障转移类型:
- 主动 – 主动(Active-Active):所有节点同时提供服务,故障自动切换
- 主动 – 备用(Active-Standby):主节点提供服务,备用节点待命
- 自动故障转移:检测到故障后自动切换(秒级)
- 手动故障转移:需要人工介入(分钟级)
故障转移时间:
快速故障转移:< 1 秒 (内存数据库、缓存)
标准故障转移:1-5 秒 (应用服务)
慢速故障转移:5-60 秒 (数据库主从切换)
3. 负载均衡(Load Balancing)
负载均衡将请求分发到多个服务实例,避免单点过载。
负载均衡层次:
- L4 负载均衡(传输层):基于 IP 和端口
- Nginx(四层模式)、HAProxy
- L7 负载均衡(应用层):基于 URL、Header
- Nginx(七层模式)、F5、SLB
负载均衡算法:
```python
轮询(Round Robin)
均匀分配请求
加权轮询(Weighted Round Robin)
根据服务器能力分配权重
最少连接(Least Connections)
分配给当前连接数最少的服务器
IP 哈希(IP Hash)
相同 IP 请求总是分配给同一服务器(会话保持)
4. 熔断降级(Circuit Breaker)
当依赖服务故障时,自动熔断,防止故障扩散。
熔断状态:
- 关闭(Closed):正常服务
- 打开(Open):拒绝请求,直接返回降级结果
- 半开(Half-Open):试探性恢复,成功则关闭
熔断器示例:
java
// 使用 Resilience4j 实现熔断
@CircuitBreaker(name = "userService",
failureRateThreshold = 50,
waitDurationInOpenState = 10000,
permittedNumberOfCallsInHalfOpenState = 3)
public User getUser(Long userId) {
return userService.getUser(userId);
}
高可用架构模式
模式一:集群部署
客户端请求
↓
负载均衡器(Nginx/SLB)
↓
┌──────────────┬──────────────┬──────────────┐
│ 应用服务器 1 │ 应用服务器 2 │ 应用服务器 3 │
│ (实例 A) │ (实例 B) │ (实例 C) │
└──────────────┴──────────────┴──────────────┘
↓ ↓ ↓
┌──────────────────────────────────────────┐
│ 数据库主从集群 │
│ 主库(写) → 从库 1(读) → 从库 2(读) │
└──────────────────────────────────────────┘
模式二:微服务架构
API 网关
↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 用户服务 │ │ 订单服务 │ │ 支付服务 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
↓ ↓ ↓
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Redis 集群 │ │ MySQL 集群 │ │ 消息队列 │
└────────────┘ └────────────┘ └────────────┘
模式三:读写分离
写请求 → 主库(Master)
读请求 → 从库(Slave1、Slave2...)
主从同步方式:
├─ 同步复制:数据一致性高,性能低
├─ 异步复制:性能高,数据可能有延迟
└─ 半同步复制:平衡方案
模式四:缓存分层
┌──────────────────────────────────────┐
│ 本地缓存(Cache Aside) │
│ (Guava/Caffeine) │
└──────────────────────────────────────┘
↓
┌──────────────────────────────────────┐
│ 分布式缓存(Redis 集群) │
│ (哨兵模式 + 集群模式) │
└──────────────────────────────────────┘
↓
┌──────────────────────────────────────┐
│ 数据库(MySQL) │
└──────────────────────────────────────┘
容灾方案
方案一:主从切换
适用场景:单机部署,低成本容灾
实现步骤:
bash
1. 监控主库状态
while true; do
if ! is_master_alive; then
promote_slave_to_master()
update_dns_record()
break
fi
sleep 5
done
2. 主从切换流程
检测故障 → 提升从库 → 修改配置 → 验证服务
优点:实现简单,成本低
缺点:切换过程有短暂停机
方案二:同城双活
适用场景:城市级灾备,高可用性要求
架构设计:
机房 A(主) 机房 B(从)
┌─────────┐ ┌─────────┐
│ 应用集群│ ←双向同步→ │ 应用集群│
└────┬────┘ └────┬────┘
↓ ↓
┌─────────┐ ┌─────────┐
│ 数据库主│ ←主从复制→ │ 数据库从│
└─────────┘ └─────────┘
流量分发:
- 50% 流量到机房 A
- 50% 流量到机房 B
- 跨机房调用延迟:< 10ms
优点:故障自动切换,数据实时同步
缺点:需要两个机房,成本高
方案三:异地多活
适用场景:国家级灾备,金融级高可用
架构设计:
北京机房 上海机房 广州机房
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 用户数据 │ 异步同步 │ 订单数据 │ 异步同步 │ 支付数据 │
│ (部分) │ ──────────→ │ (部分) │ ──────────→ │ (部分) │
└─────────┘ └─────────┘ └─────────┘
全局负载均衡(GSLB):
- 北京用户 → 北京机房
- 上海用户 → 上海机房
- 广州用户 → 广州机房
- 故障自动切换 → 就近分流
优点:异地容灾,故障影响最小化
缺点:架构复杂,数据一致性挑战
方案四:跨区域部署
AWS 区域架构示例:
Region: cn-north-1(北京)
├─ AZ-1(可用区 1)
│ ├─ EC2 实例 A
│ ├─ RDS 主库
│ └─ ElastiCache 集群
├─ AZ-2(可用区 2)
│ ├─ EC2 实例 B
│ └─ RDS 从库
└─ ELB 负载均衡
跨区域容灾:
- 数据同步到 cn-northwest-1(银川)
- 故障时切换至备用 Region
高可用最佳实践
1. 消除单点故障
yaml
检查清单
- [ ] 负载均衡器:使用双机热备或云服务
- [ ] 数据库:主从复制 + 自动故障转移
- [ ] 缓存:集群部署 + 数据冗余
- [ ] 消息队列:集群部署 + 持久化
- [ ] 应用服务器:多实例 + 健康检查
2. 健康检查与自动恢复
java
// Spring Boot 健康检查配置
management:
health:
redis:
enabled: true
db:
enabled: true
endpoints:
web:
exposure:
include: health,info
健康检查配置
livenessProbe:
httpGet:
path: /actuator/health/live
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
3. 限流与降级
java
// 使用 Sentinel 实现限流
@Resource
private FlowRuleManager flowRuleManager;
public void initFlowRules() {
List
FlowRule rule = new FlowRule();
rule.setResource("getUser");
rule.setCount(100); // QPS 限制
rule.setGrade(RuleLimitMetric.QPS);
rules.add(rule);
flowRuleManager.loadRules(rules);
}
// 降级策略
@SentinelResource(value = "getUser", blockHandler = "handleException")
public User getUser(Long id) {
return userService.getUser(id);
}
public User handleException(Long id, BlockException ex) {
// 降级逻辑
return new User("降级用户");
}
4. 监控与告警
yaml
Prometheus 监控配置
scrape_configs:
- job_name: 'services'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app1:8080', 'app2:8080', 'app3:8080']
告警规则
groups:
- name: high-availability
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05
for: 2m
annotations:
summary: "错误率过高"
- alert: ServiceDown
expr: up == 0
for: 1m
annotations:
summary: "服务不可用"
```
实际案例分析
案例一:电商大促高可用架构
背景:双 11 大促,订单量峰值 10 万笔/秒
架构方案:
- 弹性伸缩:K8s HPA 自动扩容到 500 个实例
- 读写分离:数据库主从复制,3 个从库分担读请求
- 缓存预热:商品数据提前加载到 Redis 集群
- 限流降级:非核心服务降级,保护核心交易链路
- 异地容灾:主备数据中心异地部署
- 三机房部署:北京、上海、广州三地三活
- 数据库多活:基于 TSO 的全局时钟同步
- 自动故障转移:5 秒内完成主库切换
- 熔断保护:依赖服务故障自动熔断
- 全链路监控:实时追踪每一笔交易
- 消除单点故障:通过冗余和集群部署
- 自动故障转移:快速检测和切换
- 负载均衡:合理分配流量
- 容灾方案:同城双活、异地多活
- 监控告警:实时发现问题
- 根据业务需求选择合适的可用性等级
- 不要过度设计,平衡成本与收益
- 持续优化,定期演练容灾预案
- 建立完整的监控和应急响应机制
结果:双 11 零故障,系统稳定运行
案例二:金融交易系统高可用设计
背景:证券交易系统,要求 99.999% 可用性
架构方案:
结果:连续 3 年可用性达到 99.999%,年停机时间低于 5 分钟
总结
高可用架构设计是系统稳定性的保障,需要:
核心建议:
通过合理的高可用架构设计,可以让系统在面对故障时保持韧性,确保业务连续性。



发表评论