调整 HAProxy 的 maxconn 参数并不是单纯改大数字,需要先确认操作系统文件描述符限制和后端服务器承载能力,否则改大了反而会导致连接排队过长或资源耗尽。
先说结论:maxconn 调整必须配合系统 ulimit 限制和后端实际处理能力,盲目调大可能引发队列堆积或内存溢出。
- 先定位:通过 stats 页面或日志确认当前连接数是否触及上限
- 先做:同步调整系统文件描述符限制与 HAProxy 配置
- 再验证:观察错误率、排队长度及系统资源占用
核心配置示例
在 haproxy.cfg 中,maxconn 可以在 global、frontend 和 backend 三个层级设置。建议 global 值略大于所有 frontend 之和,后端 server 需单独限制以防单点过载。
global
maxconn 4096
...
defaults
timeout queue 5000
...
frontend http_front
bind *:80
maxconn 2000
...
backend web_servers
balance roundrobin
server web1 192.168.1.1:80 maxconn 100 check
持久化系统限制(关键步骤)
仅使用 ulimit -n 命令仅对当前 shell 有效,systemd 管理的服务不会继承。必须修改 service 文件以确保重启后生效。
1. 编辑 systemd 配置
执行 systemctl edit haproxy 创建覆盖配置,或直接修改服务文件:
[Service]
LimitNOFILE=65535
2. 重载 systemd 并重启 HAProxy
systemctl daemon-reload
systemctl restart haproxy
3. 验证限制是否生效
cat /proc/$(pidof haproxy)/limits | grep "Max open files"
验证与监控
重载后访问 stats 页面,关注以下指标:
- scur/smax:当前/最大会话数,接近 maxconn 说明需调整。
- qcur/qmax:当前/最大队列长度,持续增长说明后端处理不足。
- err/bout:错误计数,503 错误增加通常意味着连接被拒绝。
常见坑与排查
1. 系统限制未生效:只改了 HAProxy 配置,忘了改 systemd 的 LimitNOFILE,导致启动失败或实际不生效。
2. Global 限制过小:global maxconn 限制了所有前端的总和,需确保大于各 frontend 之和。
3. 后端单点过载:后端 server 行没有设置 maxconn,导致单个后端服务器被压垮。
4. 队列超时:忽略了 timeout queue 设置,连接排队太久导致客户端超时,建议设置合理超时时间。