与大多数服务器软件相比,HAProxy 配置文件很短,却决定着每个请求如何到达您的应用。如果您打算在网站或 API 前面放一台负载均衡器,作为迈向高可用服务器配置的一步,或者接手了一台没人完全看得懂的,那么逐段阅读这个文件会很有帮助。本指南以当前 3.x 版本为例,讲解 Web 应用的典型 HAProxy 配置:各部分的作用、最重要的选项,以及导致故障的常见错误。
HAProxy 配置的四个部分
- global 设置进程级选项:日志、HAProxy 运行所用的用户、TLS 默认值,以及 Runtime API 使用的管理套接字。
- defaults 保存其下所有部分继承的设置,最重要的是模式(http 或 tcp)和超时。缺少超时是连接堆积的典型原因,HAProxy 启动时会对此发出警告。
- frontend 描述 HAProxy 监听的内容:地址、端口、证书,以及决定由哪个后端接收每个请求的规则。
- backend 列出均衡器后面的服务器、流量如何在它们之间分配,以及如何检查它们的健康状况。
每次修改后,先用 haproxy -c -f /etc/haproxy/haproxy.cfg 检查文件,再进行重新加载。通过 systemd 重新加载时,会用新配置启动新进程,而现有连接仍在旧进程上完成。
用文字说明的 HAProxy 配置示例
一个带有两台应用服务器的企业网站,常见的布局如下:
- 前端绑定 80 端口,把每个请求重定向到 HTTPS;同时绑定 443 端口,使用 ssl 和存放证书的 crt 目录。
- 前端中的规则把路径以 /api 开头的请求发送到 API 后端,其余全部发送到 Web 后端。
- 每个后端有一行 balance、一个 HTTP 健康检查和两行 server,每行都带 check 关键字。
- 前端用 option forwardfor 添加 X-Forwarded-For 头,并设置 X-Forwarded-Proto,这样应用就能记录访客的真实地址,并知道原始请求使用的是 HTTPS。
最后一点很容易被忽略。没有这些头,均衡器后面的应用会把每位访客都看作来自 HAProxy 自己的地址,有些还会因为以为请求是通过普通 HTTP 到达而造成重定向循环。
选择负载均衡算法
- roundrobin 是默认值,轮流分配并遵循服务器权重。适合短小且相似的请求。
- leastconn 把新连接发给活动连接最少的服务器。当请求持续时间差异很大时更合适,例如报表、上传或长连接。
- source,或基于头部或 URL 的哈希,让同一个客户端或资源始终落在同一台服务器上。适用于缓存,不太适合均匀分摊负载。
权重可以让更大的服务器承担更大的份额,权重为零则保留服务器的配置,但不再向它发送新请求。
反映真实情况的 HAProxy 健康检查设置
单独使用 check 关键字只测试 TCP 端口是否应答,而运行中的 Web 服务器背后的应用即使崩溃,端口也照样应答。HTTP 的 HAProxy 健康检查会请求一个真实页面:option httpchk 配合 http-check send 和 http-check expect,可以请求 /health 之类的路径并要求状态码 200。好的健康检查端点会触及重要的依赖项(如数据库),同时自身运行成本不高。
时间参数按服务器设置:inter 为间隔,fall 为连续失败多少次将服务器标记为下线,rise 为成功多少次让它恢复。检查过于激进,会在短暂变慢时把健康的服务器摘除;检查过于迟缓,则会继续把访客送到已宕机的服务器。健康检查是我们审查现有 HAProxy 负载均衡器配置时最先看的内容之一。
HAProxy 会话保持与 HAProxy SSL 终止
如果应用把登录或购物车保存在本地文件或内存中,访客一旦落到另一台服务器就会丢失会话。最好的解决办法在应用端:把会话存放在 Redis 或数据库等共享位置。无法做到时,HAProxy 会话保持在后端使用 cookie 指令,例如 cookie SERVERID insert indirect nocache,并在每行 server 上设置一个 cookie 值。之后 HAProxy 把每位访客固定在一台服务器上,只有该服务器故障时才会把他们转移走。
HAProxy SSL 终止是指由 HAProxy 处理 TLS,并通过内部网络把普通 HTTP 传给服务器。这样证书集中在一处,也让 HAProxy 能读取请求以进行路由。如果 HAProxy 与后端之间的链路要穿过您无法控制的网络,请在 server 行加上 ssl 和证书验证,对这一段也进行加密。
用 HAProxy Runtime API 排空服务器
要实现零停机部署,先把一台服务器摘出轮询,更新、检查,再放回去。HAProxy Runtime API 无需编辑文件即可做到这一点。通过 global 部分定义的管理套接字,执行 set server web/app1 state drain 之类的命令,新访客就不再到达 app1,而现有会话继续完成;state ready 则让它重新投入服务。部署脚本可以用这种方式排空服务器,等待其连接数降到零,然后继续。通过套接字所做的更改不会写入配置文件,所以永久性的修改仍应放在文件里。
同一个套接字以及内置的统计页面会显示每台服务器的状态和健康检查结果;请把两者都限制为仅管理员可用。每条指令和命令都记录在按版本组织的官方 HAProxy 文档中。
常见问题:HAProxy 配置
一台 HAProxy 可以同时处理网站和其他服务吗?
可以。同一份配置既能以 http 模式均衡网站,也能以 HAProxy TCP 模式均衡数据库或邮件等服务,各自拥有自己的前端和后端。在 TCP 模式下,HAProxy 直接转发连接而不读取内容。
应该运行哪个 HAProxy 版本?
生产环境请使用长期支持分支,例如 3.2。发行版软件包往往落后于当前分支,因此请确认您的服务器实际安装的是哪个版本;HAProxy 项目列出了其维护中的分支,并为 Debian 和 Ubuntu 提供了指向较新软件包的说明。
HAProxy 后面需要几台服务器?
为了冗余至少两台,每台都能单独承担峰值流量。否则,为部署而排空一台,或因故障损失一台,都会在最不合适的时刻让另一台过载。
正在规划负载均衡器,或想请人帮您复核现有配置?我们的 HAProxy 负载均衡器安装与配置服务涵盖围绕您的应用规划的健康检查、TLS 终止和故障切换,服务于洛杉矶(Los Angeles)及更远地区的企业。后端通常也需要关注,请参阅我们的 Apache Web 服务器优化服务。请联系我们,并简要描述您的服务器和流量。




