香港服务器容灾方案:主备切换 + 异地多活 + RTO/RPO目标设计完整实战

香港服务器容灾方案:主备切换 + 异地多活 + 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 分钟以内」,对任何有业务连续性要求的团队都值得投入。

Telegram