拿到云服务器后想把流量均匀地导到多台后端应用上,HAProxy几乎是绕不开的一个选择。它占用资源少、转发速度快,而且能同时处理四层(TCP)和七层(HTTP)的代理需求。下面这张图可以帮你直观理解HAProxy在架构中的位置:客户端请求先打到HAProxy监听端口,再由它根据配置规则分发给后方的云服务器集群,整个过程对用户透明。

云服务器上安装与基础启动
在CentOS或Ubuntu这类常见的云服务器镜像上,HAProxy通常已经打包在系统仓库里,一条命令就能装好。以CentOS 7/8为例,执行yum install haproxy -y;Ubuntu则使用apt install haproxy -y。装完之后先不要急着改配置文件,建议用haproxy -v确认一下版本,目前主流稳定版在2.4以上,对多线程和SSL的支持会更完善。
HAProxy的默认配置路径是/etc/haproxy/haproxy.cfg,它的结构分为global、defaults、frontend、backend和listen几块。global段控制进程级参数,比如运行用户、最大连接数;defaults段给后续的frontend和backend提供默认值,可以减少重复书写。初次接触的建议先保留global和defaults的默认值,把注意力集中在前端和后端配置上。
启动服务前可以先做一次配置语法检查,用haproxy -c -f /etc/haproxy/haproxy.cfg,如果输出“Configuration file is valid”就说明没问题了。然后启动:systemctl start haproxy,并设为开机自启systemctl enable haproxy。通过netstat -tlnp | grep haproxy能看到监听端口是否已经起来。
TCP模式:高效的四层负载均衡
如果后端跑的是MySQL、Redis或者没有HTTP协议的TCP服务,那就得用TCP模式。在HAProxy里,只需在frontend或listen段落中指定mode tcp,它就会工作在第四层,只检查IP和端口,不解析HTTP内容,因此性能开销极低,长连接转发基本没有额外延迟。
一个典型的TCP代理配置可以这样写:创建一个listen块,同时承担前端监听和后端服务器组的角色。比如监听3306端口,并把流量转发给多台MySQL云服务器。代码片段如下:
listen mysql_cluster
bind *:3306
mode tcp
balance leastconn
option tcplog
server db1 192.168.1.10:3306 check port 3306 inter 3s rise 2 fall 3
server db2 192.168.1.11:3306 check port 3306 inter 3s rise 2 fall 3
server db3 192.168.1.12:3306 check port 3306 inter 3s rise 2 fall 3
这里的balance leastconn表示把新连接交给当前活动连接数最少的后端,适合数据库这类长连接场景。每个server后面的check参数开启了健康检查,HAProxy会定期用TCP握手探测后端端口是否可达,inter 3s是探测间隔,rise 2表示连续两次成功才认为服务在线,fall 3则是连续三次失败后标记为宕机。还有一点需要注意,如果后端数据库之间是主从复制架构并且希望写操作只走主库,可以搭配MySQL的读写分离中间件,或者用HAProxy的tcp-request content规则配合检查发来的数据包做转发决策,不过这种深度解析会损失一部分性能,非特殊场景下更推荐在应用层处理读写分离逻辑。
HTTP模式:七层内容智能分发
面向Web应用时,就要把mode切换为http。这时候HAProxy能解析HTTP头、URL、Cookie,从而按域名、路径或参数把请求分发给不同的后端集群。例如一台云服务器上的HAProxy可以同时反向代理主站和API服务,两个域名都解析到同一个公网IP,但后端其实指向不同的服务器组。
配置时至少需要一个frontend和一个backend。frontend里写mode http并绑定80端口,然后通过acl(访问控制列表)定义流量分类规则,再指明使用哪个backend。以下是一个同时处理主站和移动API的示例:
frontend http_front
bind *:80
mode http
option httplog
acl is_api hdr(Host) -i api.ippipp.com
acl is_mobile path_beg /m/
use_backend api_servers if is_api
use_backend mobile_servers if is_mobile
default_backend web_servers
backend web_servers
mode http
balance roundrobin
cookie SERVERID insert indirect nocache
server web1 192.168.2.10:80 check cookie w1
server web2 192.168.2.11:80 check cookie w2
backend api_servers
mode http
balance roundrobin
option httpchk GET /health
server api1 192.168.3.10:80 check inter 2s rise 2 fall 2
server api2 192.168.3.11:80 check inter 2s rise 2 fall 2
这里用了常见的roundrobin轮询算法。在web_servers后端还引入了基于Cookie的会话保持:cookie SERVERID insert indirect nocache会在响应中插入一个名为SERVERID的Cookie,间接模式下后端服务器不修改已有Cookie,只有初次连接时才插入。server行的cookie w1就是该服务器对应的Cookie值,这样来自同一用户的请求就会持续落在同一台后端上。对于无状态的API服务则一般不需要会话保持,但加上了option httpchk,这是一种七层健康检查,HAProxy会定期向后端发起HTTP请求(这里是 GET /health),根据返回的2xx或3xx状态码判断服务是否正常,比单纯的TCP端口检查更精准。
SSL卸载与证书配置
生产环境基本都要走HTTPS,可以把SSL证书直接配置在HAProxy上,由它负责加解密,后端服务继续用HTTP通信,这就是SSL卸载。这样能减轻应用服务器的计算压力,也方便统一管理证书。HAProxy从1.8版本开始原生支持SSL,不再需要借助stunnel这类工具。
首先需要把域名证书(包含中间证书的完整链)和私钥合成一个pem文件,顺序是证书在前、私钥在后。假设文件名为ippipp.com.pem,放在/etc/haproxy/ssl/目录下。然后在frontend中使用bind *:443 ssl crt /etc/haproxy/ssl/ippipp.com.pem。如果希望同时支持HTTP自动跳转到HTTPS,可以额外绑定80端口并做301重定向,配置如下:
frontend https_front
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl/ippipp.com.pem
mode http
redirect scheme https if !{ ssl_fc }
# ... 其他ACL和后端选择
ssl_fc是一个内建ACL,用来判断前端连接是否已经是SSL,如果不是就重定向到https。这种做法在云服务器上很常见,内部网络通信是明文的,外网访问则强制加密。
如果有多域名需要不同证书,可以在bind行后写多个crt路径,或者使用crt-list文件批量指定域名和证书的对应关系,HAProxy会自动根据SNI(Server Name Indication)选择合适的证书。SNI依赖客户端在TLS握手时发送的域名信息,现代浏览器和客户端都支持,对于旧版客户端可能需要额外注意兼容性。
高性能调优与监控
HAProxy默认参数已经能应付不少场景,但在高并发下几个内核参数和配置项值得调整。在global段,可以把maxconn设得足够高,例如maxconn 100000;同时借助云服务器多核特性,使用nbthread指定工作线程数,一般设为CPU核心数即可。还需要检查系统文件描述符限制,在云服务器的/etc/security/limits.conf里为haproxy用户提高nofile值,并在global里加上ulimit-n指定同样的大小。
关于日志,HAProxy默认的tcplog和httplog已经包含请求耗时、后端服务器、状态码等信息。但为了便于后续分析,建议在defaults段统一设置option tcplog或option httplog,并为日志文件单独配置rsyslog规则:修改/etc/rsyslog.conf,开启UDP 514端口的监听,并在haproxy.cfg的global段添加log 127.0.0.1 local2,这样就能把日志写到/var/log/haproxy.log里。一条典型的HTTP日志会包括客户端IP、前端名称、后端名称、服务器名称、处理时间、状态码、字节数等信息,排查问题十分方便。
HAProxy还内置了一个统计报表页面,通过在listen段添加stats enable并绑定一个内网端口,就能在浏览器里看到实时连接数、队列长度、服务器状态等。比如:
listen stats
bind 192.168.0.10:8404
mode http
stats enable
stats uri /haproxy-stats
stats realm HAProxy Statistics
stats auth admin:your_password
保护好这个页面,用内网IP监听并设置HTTP基础认证,是云服务器上的安全实践。
在云服务器上部署HAProxy,本质是在网络边缘搭建一个灵活的流量入口。无论是TCP层的简单转发,还是HTTP层的复杂路由,核心都是让请求更快、更稳地落到后端。只要搞清了mode、balance、check和后端池这几个模块的搭配,完全可以按自己的业务需求组合出一套可靠的负载均衡方案。