高可用架构设计详细教程

高可用架构设计详细教程

高可用架构设计详细教程

高可用架构概述

高可用(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 rules = new ArrayList<>();
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 万笔/秒

架构方案

  1. 弹性伸缩:K8s HPA 自动扩容到 500 个实例
  2. 读写分离:数据库主从复制,3 个从库分担读请求
  3. 缓存预热:商品数据提前加载到 Redis 集群
  4. 限流降级:非核心服务降级,保护核心交易链路
  5. 异地容灾:主备数据中心异地部署
  6. 结果:双 11 零故障,系统稳定运行

    案例二:金融交易系统高可用设计

    背景:证券交易系统,要求 99.999% 可用性

    架构方案

    1. 三机房部署:北京、上海、广州三地三活
    2. 数据库多活:基于 TSO 的全局时钟同步
    3. 自动故障转移:5 秒内完成主库切换
    4. 熔断保护:依赖服务故障自动熔断
    5. 全链路监控:实时追踪每一笔交易
    6. 结果:连续 3 年可用性达到 99.999%,年停机时间低于 5 分钟

      总结

      高可用架构设计是系统稳定性的保障,需要:

      1. 消除单点故障:通过冗余和集群部署
      2. 自动故障转移:快速检测和切换
      3. 负载均衡:合理分配流量
      4. 容灾方案:同城双活、异地多活
      5. 监控告警:实时发现问题
      6. 核心建议

        • 根据业务需求选择合适的可用性等级
        • 不要过度设计,平衡成本与收益
        • 持续优化,定期演练容灾预案
        • 建立完整的监控和应急响应机制

        通过合理的高可用架构设计,可以让系统在面对故障时保持韧性,确保业务连续性。

标签

发表评论