负载均衡与反向代理:故障转移的三大支柱
做高可用,绕不开反向代理和负载均衡。
这三兄弟——Nginx、HAProxy、LVS——我几乎每天都在接触。不少人觉得它们功能重叠,非要选一个。我个人的习惯是:别急着站队,先搞清楚它们的定位。这章我们就掰开揉碎了聊聊。
一、Nginx:七层代理里的多面手
Nginx 本质上是一个反向代理服务器。它能解析 HTTP 协议,所以能做的动作远不止转发请求。我之前有一个项目,客户端请求里带了各种奇怪的 header,后端服务认不出,全靠 Nginx 的 rewrite 模块做清洗。
它的工作分两步:
- 接收请求:Nginx 的 worker 进程监听端口,拿到完整 TCP 连接后解析 HTTP 报文。
- 选择后端:根据 URL、cookie 或请求头,从 upstream 块里挑一个 server。
upstream backend {
server 10.0.1.2:8080 weight=3;
server 10.0.1.3:8080 weight=2;
server 10.0.1.4:8080 backup;
keepalive 32;
}
server {
listen 80;
location /api/ {
proxy_pass http://backend;
proxy_next_upstream error timeout http_500;
}
}
Nginx 的健康检查。官方开源版只支持被动检查——响应超时或返回 5xx 就标记为不可用,下次请求自动跳过。如果你需要主动探查,推荐用 nginx_upstream_check_module 或者直接用商业版的 Plus。
有回我帮一家电商做压测,发现 Nginx 频繁把正常的 pod 标记为失效。查了半天,原因是后端慢查询导致响应超过 30 秒,触发了 proxy_next_upstream。这就是典型的被动检查缺陷——它只看结果,不问原因。
二、HAProxy:负载均衡的瑞士军刀
HAProxy 是专业的 TCP/HTTP 负载均衡器。你想想看,它的资源消耗能小到什么程度?我见过单台 HAProxy 扛下 50 万并发连接,CPU 占用还不到 30%。
健康检查是 HAProxy 的强项。它支持三种模式:
| 模式 | 检查方式 | 典型场景 |
|---|---|---|
| option httpchk | 发送 HTTP 请求,检查返回状态码 | Web 应用健康探测 |
| option tcp-check | 打开 TCP 连接并发送期望字符串 | Redis、MySQL 等自定义协议 |
| option mysql-check | 专用的 MySQL ping 检查 | 数据库读写分离 |
backend web_servers
mode http
balance roundrobin
option httpchk GET /health HTTP/1.1\r\nHost:\ example.com
server app1 10.0.1.5:80 check inter 3000 fall 3 rise 2
server app2 10.0.1.6:80 check inter 3000 fall 3 rise 2
参数 inter 3000 fall 3 rise 2 的意思是:每 3 秒检查一次,连续失败 3 次才标记为不可用,连续成功 2 次才恢复。这样的好处很明显——避免瞬时的网络抖动导致误杀。我曾经就因为 fall 设成 1,每次发版重启期间 HAProxy 就把所有节点踢掉了,导致长达 2 分钟的 503。
三、LVS:Linux 内核级别的四层转发
LVS 和前面两个完全不同。它工作在 OSI 模型的第四层,运行在 Linux 内核空间。说白了,它就是一个高性能的 IPVS 模块。
LVS 有三种工作模式,我经常用一张表给团队对比:
| 模式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| DR(直接路由) | LVS 只改 MAC 地址,后端直接回包给客户端 | 性能最高,无回包瓶颈 | 后端需要配置 VIP 和 ARP 抑制 |
| TUN(隧道) | LVS 封装 IPIP 隧道发给后端 | 支持跨机房转发 | 隧道开销大,配置复杂 |
| NAT | LVS 做 DNAT,请求和回包都经过它 | 后端不用做特殊配置 | 回包走 LVS 成为瓶颈 |
大多数高并发场景我推荐 DR 模式。但要注意,后端服务器的回包不能经过 LVS,否则会形成环路。这个坑我踩过——配了个 RIP 的默认网关指向 LVS,结果所有回应包又回到了 LVS,形成死循环。改成 169.254.0.1 的直连路由才解决。
# 配置虚 IP
ip addr add 10.0.0.100/32 dev lo:0
# 添加集群服务
ipvsadm -A -t 10.0.0.100:80 -s rr
# 添加后端真实服务器(DR 模式)
ipvsadm -a -t 10.0.0.100:80 -r 10.0.1.10:80 -g
ipvsadm -a -t 10.0.0.100:80 -r 10.0.1.11:80 -g
至于健康检查,LVS 内核里自带了一个叫 keepalived 的伴侣程序。它负责做健康探测,如果某个 RS 挂了,它会通知内核的 IPVS 模块把它从调度列表中摘除。
- Nginx:擅长七层路由,健康检查被动为主,故障转移依赖 proxy_next_upstream。
- HAProxy:独有的精细控制,支持多协议自定义健康检查,适合复杂后端。
- LVS+Keepalived:纯四层转发,性能极致,健康检查由 Keepalived 完成,适合入口层。
四、选型建议:得看你的场景
说了这么多,实战中怎么选?我个人的粗框架是这样:
- 小规模集群(5-20 台):直接用 Nginx,七层能力强,能当网关还能做静态资源服务。健康检查够用就行。
- 中大型服务(50-500 台):HAProxy 作为中间层,做精细的流量调度和健康检查。前面再挂一层 LVS 做入口分流。
- 要求极致性能:LVS DR 模式做入口,HAProxy 做 API 网关。两者结合,既能抗流量又能做精细路由。