多台服务器如何实现业务高可用?负载均衡、故障切换与数据同步

企业已经购买多台服务器,业务却仍会因一台数据库宕机或一个入口地址失效而中断,这是因为“机器数量多”不等于高可用。真正的业务高可用,需要请求能够分散、故障能够被检测并自动切走、状态与数据能够一致恢复,还要避免负载均衡器、存储和机房本身成为新的单点。

一、从可用性目标和故障域开始设计

设计前先定义 SLO、RTO 和 RPO。SLO 表示希望达到的服务目标,RTO 是可接受的恢复时间,RPO 是可接受的数据丢失窗口。99.9% 年可用率理论停机约 8.76 小时,99.99% 约 52.6 分钟,提升一个小数位不只是多买一台机器,还需要自动化、冗余网络、演练与更严格的变更管理。

然后枚举故障域:进程、操作系统、物理机、交换机、机柜、机房和地域。两台服务器若连接同一电源、同一交换机且放在同一机柜,只能防部分主机故障。应用多活、数据库主备和负载均衡双机应跨越与目标匹配的故障域,同时权衡跨域延迟和数据一致性。

层级高可用手段主要风险验证重点
入口双负载均衡、浮动地址或 DNS 调度入口单点、缓存与 TTL切换时间、连接影响
应用多实例、健康检查、无状态化会话和本地文件摘除与恢复、容量余量
数据库主备、复制、仲裁脑裂、复制延迟、误切换数据一致性与回切
存储多副本、快照、异地备份同步复制故障扩散恢复演练、校验
机房跨故障域或跨地域链路延迟、成本、复杂度整站切换与依赖清单

二、负载均衡与健康检查要反映真实业务

负载均衡可以工作在四层或七层。四层按 TCP/UDP 转发,性能高且协议透明;七层理解 HTTP,可按域名、路径、请求头路由,并能做更细健康检查。算法可选择轮询、最少连接、权重或一致性哈希。选择重点不是名称,而是流量特征和后端是否有状态。

健康检查不能只测试端口打开。应用线程池耗尽、数据库连接失败时,端口仍可能响应。更可靠的检查端点应验证进程、关键依赖和只读业务,但又不能执行高成本查询。设置合理的间隔、超时、失败阈值和恢复阈值,避免短暂抖动造成频繁摘除。后端恢复后应逐步加权,防止冷缓存被瞬间流量击穿。

# HAProxy示例片段,部署前按版本校验配置
frontend web_in
    bind *:80
    default_backend app_pool
backend app_pool
    balance leastconn
    option httpchk GET /healthz
    http-check expect status 200
    server app1 10.0.0.11:8080 check inter 2s fall 3 rise 3
    server app2 10.0.0.12:8080 check inter 2s fall 3 rise 3
# 检查服务监听、健康端点与配置语法
ss -lntp
curl -fsS http://10.0.0.11:8080/healthz
curl -fsS http://10.0.0.12:8080/healthz
haproxy -c -f /etc/haproxy/haproxy.cfg

负载均衡器自身也要冗余。常见方式是两台节点配合 VRRP 漂移虚拟 IP,或使用具备冗余能力的托管负载均衡。切换前应确认二层网络、ARP 更新、安全策略和会话保持行为。若依赖 DNS 切换,则受递归缓存和 TTL 影响,不能假设所有客户端立即生效。

三、应用层要无状态化并预留 N+1 容量

应用实例本地保存登录会话、上传文件或定时任务锁时,请求切到另一台可能失败。高可用改造应把会话放到共享且有冗余的缓存或使用可验证的令牌,把上传文件放到共享对象或分布式存储,把定时任务改为带分布式锁的单例调度。配置和密钥需一致发布,但不能把生产密钥直接写入代码仓库。

容量至少按 N+1 计算。假设峰值需要两台服务器、每台安全承载 500 QPS,就不应只部署两台并让其各跑满 500 QPS;任意一台故障后剩余节点会过载。可以按“所需台数等于峰值 QPS 除以单机安全承载力,再乘冗余系数并向上取整”估算。单机安全承载力要用满足 P95/P99 延迟目标时的结果,而不是压到错误率上升后的极限值。

# 使用常见HTTP压测工具验证后端基线,目标必须是测试环境
wrk -t4 -c200 -d120s --latency http://10.0.0.11:8080/test
# 压测同时观察CPU、内存、连接和I/O
mpstat -P ALL 1
vmstat 1
iostat -x 1

四、数据同步、故障切换与脑裂防护

数据层是多台服务器高可用的难点。同步复制通常能降低 RPO,但写延迟受最慢副本和网络影响;异步复制性能较好,却可能在主库突然故障时丢失尚未复制的数据。半同步或多数派提交是在性能与一致性之间折中。选择必须由业务能否接受数据回退决定,不能只追求“零丢失”口号。

自动故障切换需要可靠仲裁。两节点系统若网络隔离,双方都认为对方故障并同时对外写入,就会形成脑裂。应引入奇数投票节点、仲裁服务或 fencing 机制,确保旧主被隔离后再提升新主。切换还要更新连接入口、只读读写角色,并验证复制延迟已经在允许范围内。

同步不是备份。误删除或错误更新可能立即同步到所有副本,勒索加密也会扩散。高可用体系仍需独立、版本化、隔离权限的备份,并定期恢复校验。

# 以MySQL兼容环境为例查看复制状态,具体命令按版本与拓扑调整
mysql -e "SHOW REPLICA STATUS\G"
# 关注Seconds_Behind_Source、IO/SQL线程、错误信息和GTID位置
# 切换前后都执行应用级读写与数据校验,而非只看进程存活

五、网络和存储不能成为隐藏单点

应用节点之间的复制、心跳和用户流量应合理隔离,至少在监控上能够区分。链路质量需关注延迟、抖动、丢包与双向吞吐。跨地域同步尤其要测高峰时段,不能只用机房内低延迟推断公网表现。

# 节点间网络质量与吞吐测试
ping -c 100 10.0.0.12
mtr -rw -c 100 10.0.0.12
# 对端启动 iperf3 -s
iperf3 -c 10.0.0.12 -P 4 -t 60
iperf3 -c 10.0.0.12 -P 4 -t 60 -R

存储延迟上升会让健康检查误判应用故障。用 iostat -x 1 观察 await 与 %util,当利用率持续接近百分之百且 await 明显恶化时,说明设备可能饱和。dd 只能反映顺序复制,fio 可模拟 4K 随机读、队列深度和多任务,更适合验证数据库存储,但必须在安全测试文件上执行。

六、高可用落地与演练步骤

  1. 定义应用 SLO、RTO、RPO,并列出进程、主机、网络、存储、机房等故障域。
  2. 压测得到单机安全承载力,按峰值、增长和 N+1 冗余确定实例数。
  3. 部署冗余负载均衡和业务级健康检查,将应用会话、文件与任务状态外置。
  4. 选择符合一致性目标的数据复制与仲裁机制,明确自动切换和人工确认边界。
  5. 建立端到端监控,覆盖入口成功率、P95/P99、后端健康、复制延迟与容量余量。
  6. 先在测试环境注入进程停止、主机断网、磁盘变慢和主库故障,再在受控窗口演练生产。
  7. 记录检测、切换、恢复、数据校验和回切时间,修订预案并定期复演。

小结与避坑建议

多台服务器如何实现业务高可用,核心不是堆设备,而是消除端到端单点。负载均衡负责分流与摘除,应用无状态化保证请求可迁移,数据复制与仲裁保证一致切换,备份负责处理同步体系无法解决的逻辑灾难。常见坑包括只检查端口、两台后端都跑满、数据库双主无仲裁、把复制当备份,以及只演练切换不演练回切。高可用必须通过故障注入证明;没有定期演练的架构,只能算高可用设计,不能算高可用能力。