香港服务器容灾方案:主备切换 + 异地多活 + RTO/RPO目标设计完整实战
机房断电、光纤被挖断、DDoS 攻击、服务器硬件故障——这些小概率事件每年都在真实发生。没有容灾方案的业务,遇到这类事件就是完全停摆。本文从 RTO/RPO 目标制定开始,构建一套分级的香港服务器容灾体系,从简单的「主备切换」到完整的「异地多活」,按业务规模选择合适的实施级别。
一、容灾核心指标
<code"> RTO(Recovery Time Objective):最大可接受宕机时长 RPO(Recovery Point Objective):最大可接受数据丢失量 业务分级: ┌─────────────────────────────────────────────────────┐ │ 级别 │ 业务类型 │ RTO │ RPO │ ├───────┼───────────────────────┼───────┼─────────────┤ │ L1 │ 核心交易(支付/订单) │ <5分 │ <1分 │ │ L2 │ 主站/API(用户访问) │ <30分 │ <15分 │ │ L3 │ 运营后台 │ <4小时│ <1小时 │ │ L4 │ 内部工具/监控 │ <24小时│ <6小时 │ └─────────────────────────────────────────────────────┘
二、Level 1:Cloudflare 健康检查 + 自动 DNS 切换
<code">
架构:
主站(香港 VPS 1,CN2 GIA)→ Cloudflare → 用户
↓ 主站故障时
备站(新加坡 VPS,BGP)
成本:
主站:¥200/月(香港 CN2 GIA)
备站:¥80/月(新加坡 BGP)
合计:¥280/月
Cloudflare 配置:
DNS → yourdomain.com → Load Balancing
<code"> 在 Cloudflare 控制台配置负载均衡: 1. Traffic → Load Balancing → Create Load Balancer - Hostname: yourdomain.com - Fallback Pool: Singapore-VPS 2. Create Health Checks - URL: https://yourdomain.com/health - Interval: 60s - Failure threshold: 2(连续2次失败触发切换) - Expected Status: 200 - Expected Body: "ok"(检查响应内容) 3. 设置 Pool 优先级: - Primary Pool: HK-VPS(权重100) - Backup Pool: Singapore-VPS(仅主池失败时启用) 故障切换逻辑: 主站两次健康检查失败(约2分钟)→ Cloudflare 自动将 DNS 切换到备站 备站恢复 → 下一个成功的健康检查后自动切回主站
三、数据库主从同步(保证 RPO < 1 分钟)
<code"># 主库(香港)配置 # /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] server-id = 1 log_bin = mysql-bin binlog_format = ROW gtid_mode = ON enforce_gtid_consistency = ON sync_binlog = 1 # 每次提交都 flush(保证 RPO 最低) # 备库(新加坡)配置 server-id = 2 relay_log = relay-bin read_only = ON # 备库只读 gtid_mode = ON enforce_gtid_consistency = ON # 主库创建复制账号 mysql -uroot -p << 'EOF' CREATE USER 'replica'@'%' IDENTIFIED BY 'ReplicaPass2026'; GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%'; FLUSH PRIVILEGES; EOF
<code"># 备库配置复制
mysql -uroot -p << 'EOF'
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '香港主库IP',
SOURCE_USER = 'replica',
SOURCE_PASSWORD = 'ReplicaPass2026',
SOURCE_AUTO_POSITION = 1;
START REPLICA;
SHOW REPLICA STATUS\G
EOF
# 监控复制延迟
mysql -e "SHOW REPLICA STATUS\G" | grep "Seconds_Behind_Source"
# 目标:Seconds_Behind_Source < 60(1分钟内同步)四、文件同步(应用代码和上传文件)
<code"># 实时文件同步到备站(使用 lsyncd + rsync)
apt install -y lsyncd
# /etc/lsyncd/lsyncd.conf.lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/run/lsyncd.status",
statusInterval = 20,
}
sync {
default.rsync,
source = "/var/www/yourdomain.com/wp-content/uploads",
target = "root@新加坡备站IP:/var/www/yourdomain.com/wp-content/uploads",
rsync = {
archive = true,
compress = true,
rsh = "/usr/bin/ssh -i /root/.ssh/backup_key -o StrictHostKeyChecking=no",
},
}
systemctl enable --now lsyncd五、故障切换操作手册(Runbook)
<code"> ========================================= 香港服务器故障切换 SOP ========================================= 触发条件: - 主站连续 5 分钟无法访问 - Cloudflare 健康检查已自动切换 DNS 手动验证(T+0): 1. ping 香港服务器 IP → 如果无法 ping 通,联系 IDC 报障 2. 访问 https://yourdomain.com → 确认流量已切到备站 curl -v https://yourdomain.com 2>&1 | grep "Connected to" 3. 查看备站应用日志确认流量接入正常: tail -f /var/log/nginx/access.log 数据库切换(T+5分钟,如主库也故障): 1. 在备站提升备库为主库: mysql -e "STOP REPLICA; RESET REPLICA ALL;" mysql -e "SET GLOBAL read_only = OFF;" 2. 更新应用配置指向备库: sed -i 's/主库IP/备库IP/' /var/www/yourdomain.com/.env supervisorctl restart all 通知(T+10分钟): - 发送故障通知到飞书群:说明影响范围和预计恢复时间 - 联系 IDC 处理主站故障 恢复后(主站修复后): 1. 将数据从备库同步回主库(验证数据完整性) 2. 重新配置主从复制(备库 → 主库方向) 3. 在 Cloudflare 恢复原始 Pool 优先级 4. 确认流量切回主站 5. 编写事后复盘报告 =========================================
六、Level 2:异地多活架构
<code">
适合日均 GMV > ¥10 万,RTO 要求 < 5 分钟的业务
架构:
香港主节点(CN2 GIA,写请求)
│ 实时同步
新加坡节点(BGP,读请求 + 香港故障时写请求)
│ DNS 轮询(Cloudflare LB)
↓ 两个节点同时承接流量
数据一致性方案:
- 所有写请求路由到主节点(香港)
- 读请求就近路由(各区域读本地副本)
- MySQL MGR 三节点:香港×2 + 新加坡×1(Paxos 协议保证强一致)
- 会话数据存储在 Redis(主从同步,确保跨节点一致)
成本估算:
香港 4核8G CN2 GIA:¥300/月
新加坡 4核8G BGP:¥200/月
Cloudflare LB:$5/月
合计:约¥530/月
七、容灾演练(每月定期执行)
<code"># 容灾演练脚本(测试故障切换是否正常)
cat > /opt/dr-drill.sh << 'EOF' #!/bin/bash echo "=== 容灾演练开始 $(date) ===" # 1. 记录当前主站状态 echo "主站访问测试:" RESPONSE=$(curl -s -w "\n状态码:%{http_code} 时间:%{time_total}s" \ https://yourdomain.com -o /dev/null) echo $RESPONSE # 2. 模拟主站下线(不实际操作,只检查健康检查) echo "" echo "Cloudflare 健康检查状态:" curl -s "https://api.cloudflare.com/client/v4/user/load_balancers/monitors" \ -H "Authorization: Bearer $CF_API_TOKEN" | python3 -m json.tool | grep -E "health|status" # 3. 检查备站是否可以独立运行 echo "" echo "备站直接访问测试:" curl -s -w "状态码:%{http_code} 时间:%{time_total}s" \ https://新加坡备站IP -o /dev/null \ -H "Host: yourdomain.com" # 4. 检查数据库复制延迟 echo "" echo "数据库复制延迟:" mysql -h 备站IP -u replica -pReplicaPass2026 \ -e "SHOW REPLICA STATUS\G" 2>/dev/null | grep "Seconds_Behind_Source"
echo "=== 演练完成 ==="
EOF
chmod +x /opt/dr-drill.sh
# 每月第一个周六早上9点执行演练
echo "0 9 * * 6 [ \$(date +\%d) -le 7 ] && /opt/dr-drill.sh >> /var/log/dr-drill.log 2>&1" >> /etc/crontab八、RPO/RTO 验证基准
| 场景 | 目标 RTO | 实测结果 | 目标 RPO | 实测结果 |
|---|---|---|---|---|
| 主站 Web 故障 | 5 分钟 | 约 2~3 分钟(Cloudflare 自动) | 0(无状态) | 0 |
| 主数据库故障 | 15 分钟 | 约 5~10 分钟(半自动) | 1 分钟 | 约 30 秒 |
| 整个香港机房故障 | 30 分钟 | 约 15 分钟(全手动) | 5 分钟 | 约 1 分钟 |
九、总结
容灾方案的成本与 RTO/RPO 目标成正比:每年多花几千元的备站成本,换来的是机房故障时业务不中断的能力。对于香港服务器用户,Level 1 方案(Cloudflare 健康检查 + 新加坡备站 + MySQL 主从)月均增加约 ¥100~200 成本,却能将宕机时间从「可能超过 24 小时」压缩到「5 分钟以内」,对任何有业务连续性要求的团队都值得投入。