实战笔记:我用 Nginx + HAProxy 搭建高可用负载均衡的踩坑实录
大家好,我是 33blog 的运维老司机。上周公司业务量突然暴增,单台 Nginx 反向代理服务器直接被打爆,被迫连夜搭建多节点负载均衡。今天就把这次实战中趟过的坑和最终方案分享给大家,特别适合中小型网站从单节点向高可用架构过渡的场景。
为什么需要多层代理?
最开始我觉得 Nginx 本身就有负载均衡功能,直接 upstream 不就行了?但实际压测时发现:当后端服务达到 20+ 个时,单 Nginx 的 CPU 成了瓶颈。更可怕的是,这台机器如果宕机,整个服务就全挂了。
最终方案变成了:
- 第一层:2 台 HAProxy 做 TCP 层负载均衡(主备+keepalived)
- 第二层:3 台 Nginx 做 HTTP 反向代理
- 第三层:业务服务器集群
这样既解决了单点故障,又能根据协议特性分层处理。
HAProxy 配置的魔鬼细节
配置 HAProxy 时我犯了个低级错误:没开 TCP keepalive。结果长连接被中间路由器悄悄掐断,导致诡异的 502 错误。后来加上这些参数才稳定:
frontend web
bind *:80
mode tcp
option tcplog
timeout client 1h
default_backend nginx_nodes
backend nginx_nodes
mode tcp
balance roundrobin
option tcp-check
server nginx1 192.168.1.101:80 check inter 5s
server nginx2 192.168.1.102:80 check inter 5s
server nginx3 192.168.1.103:80 check inter 5s
特别注意 mode tcp
和 option tcp-check
的配合,比单纯用 HTTP 检查更节省资源。
Nginx 的调优技巧
第二层 Nginx 的优化重点在连接复用。我们的业务包含大量小图片请求,默认配置根本扛不住:
upstream backend {
keepalive 32; # 连接池大小
server 10.0.1.1:8080;
server 10.0.1.2:8080;
}
server {
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://backend;
}
}
关键点在于 keepalive
和 proxy_http_version 1.1
的组合,这比短连接模式减少了 60% 的 TCP 握手开销。不过要注意监控内存使用情况,连接数太多会 OOM。
监控方案的选择
架构复杂后,传统监控方式就力不从心了。我最后用这套组合拳:
- Prometheus + Grafana:采集 HAProxy/Nginx 的 metrics
- Elastic Stack:收集和分析访问日志
- 简单的自研脚本:定时模拟用户请求检查各层可用性
特别提醒:HAProxy 的 stats 页面一定要开,但记得加 ACL 限制访问!我就差点因为没设密码被扫描器爆破。
最终效果与反思
这套架构上线后:
- 成功扛住了日均 500 万 PV 的流量
- 单节点故障时切换时间 < 3 秒
- 整体延迟比单节点时还降低了 15%
回头看,如果预算充足直接用云负载均衡会更省事。但自己搭建的经历让我对流量调度有了更深理解,下次再遇到类似需求,我可能会尝试 Envoy 这类新方案。
你们在负载均衡方案选择上有什么经验或疑问?欢迎在评论区交流~
老司机经验就是稳,这种分层架构确实适合业务增长期,我们公司也在用类似的方案
看到HAProxy那段配置真的感同身受,去年我们也因为没开keepalive被坑惨了 😅
想问下楼主,Prometheus监控HAProxy时是用exporter还是直接读stats接口?