跳转至

第15章:高可用架构

高可用架构

15.1 高可用概述

什么是高可用

高可用是指系统在规定时间内能够持续提供服务的能力,通常用可用性百分比来衡量。

可用性指标

可用性 年度停机时间
99% 3.65天
99.9% 8.76小时
99.99% 52.56分钟
99.999% 5.26分钟

高可用的目标

  1. 消除单点故障:没有单点故障
  2. 快速故障恢复:快速从故障中恢复
  3. 数据不丢失:保证数据完整性
  4. 服务持续可用:持续提供服务

15.2 容灾备份

15.2.1 数据备份

全量备份

Bash
# MySQL全量备份
mysqldump -u root -p --all-databases > full_backup.sql

# 恢复全量备份
mysql -u root -p < full_backup.sql

增量备份

Bash
# MySQL增量备份
mysqldump -u root -p --single-transaction --flush-logs --master-data=2 > incremental_backup.sql

定时备份

Python
import schedule
import subprocess
import time

def backup_database():
    # 执行备份(使用 stdout 重定向写入文件)
    # 通过环境变量传递密码,避免命令行泄露凭据(ps aux 可见)
    import os
    env = os.environ.copy()
    env['MYSQL_PWD'] = os.environ['DB_PASSWORD']
    backup_file = f'backup_{time.strftime("%Y%m%d_%H%M%S")}.sql'
    with open(backup_file, 'w') as f:  # with自动管理资源,确保文件正确关闭
        subprocess.run(
            ['mysqldump', '-u', 'root', '--all-databases'],
            stdout=f,
            env=env,
            check=True
        )
    print(f"Backup completed: {backup_file}")

# 每天凌晨2点执行备份
schedule.every().day.at("02:00").do(backup_database)

while True:
    schedule.run_pending()
    time.sleep(60)

15.2.2 异地容灾

主备架构

Text Only
主数据中心
├── 主数据库
├── 主应用
└── 主存储

备数据中心
├── 备数据库
├── 备应用
└── 备存储

双活架构

Text Only
数据中心A
├── 数据库A
├── 应用A
└── 存储A

数据中心B
├── 数据库B
├── 应用B
└── 存储B

15.3 故障转移

15.3.1 数据库故障转移

MySQL主从切换

Bash
# 检查主库状态
mysql -u root -p -e "SHOW MASTER STATUS;"

# 提升从库为主库
mysql -u root -p -e "STOP SLAVE; RESET SLAVE;"

# 更新应用配置
# 修改数据库连接到新的主库

PostgreSQL故障转移

Bash
# 使用Patroni进行故障转移
patronictl failover

# 查看集群状态
patronictl list

15.3.2 应用故障转移

健康检查

Python
from fastapi import FastAPI, HTTPException

app = FastAPI()

@app.get("/health")
def health_check():
    # 检查数据库连接
    try:
        db.execute("SELECT 1")
    except Exception as e:
        raise HTTPException(status_code=503, detail="Database connection failed")

    # 检查Redis连接
    try:
        r.ping()
    except Exception as e:
        raise HTTPException(status_code=503, detail="Redis connection failed")

    return {"status": "healthy"}

自动故障转移

Python
import requests
import time

def check_service_health(url):
    try:
        response = requests.get(f"{url}/health", timeout=5)
        return response.status_code == 200
    except Exception as e:
        return False

def failover(primary_url, backup_url):
    # 检查主服务健康状态
    if not check_service_health(primary_url):
        print("Primary service is down, failing over to backup")
        # 切换到备份服务
        return backup_url
    else:
        return primary_url

# 定期检查
while True:
    current_url = failover(primary_url, backup_url)
    time.sleep(10)

15.4 负载均衡高可用

15.4.1 HAProxy

Bash
# HAProxy配置
frontend http-in
    bind *:80
    default_backend servers

backend servers
    balance roundrobin
    server server1 192.168.1.1:8000 check
    server server2 192.168.1.2:8000 check
    server server3 192.168.1.3:8000 check backup

15.4.2 Nginx高可用

Bash
# Nginx配置
upstream backend {
    server 192.168.1.1:8000;
    server 192.168.1.2:8000;
    server 192.168.1.3:8000 backup;
}

server {
    listen 80;

    location / {
        proxy_pass http://backend;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
    }
}

15.4.3 Keepalived

Bash
# Keepalived配置
vrrp_script check_nginx {
    script "killall -0 nginx"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 1234
    }

    virtual_ipaddress {
        192.168.1.100
    }

    track_script {
        check_nginx
    }
}

15.5 限流降级

15.5.1 限流

Python
from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)

@app.get("/api/data")
@limiter.limit("100/minute")
async def get_data(request: Request):  # async def定义异步函数;用await调用
    return {"data": []}

15.5.2 降级

Python
from circuitbreaker import circuit

@circuit(failure_threshold=5, recovery_timeout=30)
def call_external_service():
    # 调用外部服务
    response = requests.get("http://external-service/api")
    return response.json()

# 使用降级
try:
    data = call_external_service()
except Exception as e:
    # 降级逻辑
    data = get_fallback_data()

15.6 熔断器

Python
from circuitbreaker import circuit

@circuit(failure_threshold=5, recovery_timeout=30)
def call_external_service():
    # 调用外部服务
    response = requests.get("http://external-service/api")
    return response.json()

# 使用熔断器
try:  # try/except捕获异常
    data = call_external_service()
except Exception as e:
    # 熔断器打开,使用降级数据
    data = get_fallback_data()

15.7 实战练习

练习1:设计一个高可用数据库架构

设计一个高可用数据库架构: 1. 主从复制 2. 故障转移 3. 自动切换 4. 数据备份

练习2:设计一个高可用应用架构

设计一个高可用应用架构: 1. 多实例部署 2. 负载均衡 3. 健康检查 4. 故障转移

练习3:设计一个高可用系统

设计一个高可用系统: 1. 多数据中心 2. 容灾备份 3. 故障恢复 4. 演练测试

15.8 面试准备

常见面试题

  1. 什么是高可用?如何衡量?
  2. 如何设计一个高可用架构?
  3. 什么是故障转移?如何实现?
  4. 什么是容灾?有哪些方案?
  5. 什么是熔断器?如何使用?

项目经验准备

准备一个高可用项目: - 架构设计 - 遇到的挑战 - 解决方案 - 项目成果

15.9 总结

本章介绍了高可用架构,包括容灾备份、故障转移、负载均衡高可用、限流降级和熔断器。高可用是保证系统稳定运行的关键。

关键要点

  1. 高可用需要消除单点故障
  2. 容灾备份包括全量备份、增量备份、异地容灾
  3. 故障转移需要健康检查和自动切换
  4. 负载均衡高可用使用HAProxy、Nginx、Keepalived
  5. 限流降级和熔断器保护系统

全书总结

本书系统性地介绍了后端架构设计,从基础概念到高级技术,涵盖了分布式系统、数据库、缓存、消息队列、微服务、服务治理、API网关、搜索、大数据、存储、监控、安全、性能优化和高可用等核心内容。

通过学习本书,你应该能够: 1. 理解后端架构的核心概念 2. 设计高可用、高性能、可扩展的后端系统 3. 掌握主流的后端技术 4. 具备解决复杂问题的能力

祝你成为一名优秀的后端架构师! 🚀