跳转到内容
搜索 RunEntLinux 文档

仅搜索 RunEntLinux 通用文档,各发行版文档使用各自的搜索入口。

    浏览当前文档目录

    HAProxy 负载均衡

    适用于 CentOS Stream 9 & 10 / AlmaLinux 9.x & 10.x / Rocky Linux 9.x & 10.x

    HAProxy 是一款高性能的 TCP/HTTP 负载均衡器与反向代理。当一台后端服务器扛不住流量,或者你需要在升级、宕机时保持服务可用时,HAProxy 可以把请求分发到多台后端,实现横向扩展与高可用。本文带你在 EL 系统上从零搭起一套四层/七层负载均衡。

    • 安装 HAProxy 并理解配置文件的四个核心段
    • 配置 frontend 与 backend,把流量分发到多台后端服务器
    • 使用 roundrobin / leastconn 调度算法与健康检查
    • 启用统计页面观察后端状态
    • 处理 SELinux 与 firewalld 放行
    • 配置 TLS 终止与 HTTP→HTTPS 跳转
    • 了解如何配合 Keepalived 让 HAProxy 自身也高可用
    • 一台运行 EL 9.x 或 EL 10.x 的系统作为负载均衡器
    • 至少两台可访问的后端 Web 服务器(本文以 10.0.0.11 / 10.0.0.12 为例)
    • sudo 权限
    版本数据实时来自 pkgseek.com

    HAProxy 在 AppStream 仓库中提供,直接安装即可:

    安装 HAProxy
    $ sudo dnf install haproxy

    确认版本:

    查看版本
    $ haproxy -v
    HAProxy version 2.4.x ...

    HAProxy 的主配置文件是 /etc/haproxy/haproxy.cfg,由四个核心段组成:

    段作用
    global进程级全局设置:日志、运行用户、最大连接数、调优参数
    defaults为后续的 frontend/backend 提供默认值,避免重复书写
    frontend定义对外监听的地址、端口,以及把流量交给哪个 backend
    backend定义后端服务器池、调度算法与健康检查

    frontend 接收客户端请求,backend 承载真实的后端服务器,两者通过名字关联。

    下面这份配置监听 80 端口,把 HTTP 请求轮询分发到两台后端 Web 服务器。编辑 /etc/haproxy/haproxy.cfg:

    /etc/haproxy/haproxy.cfg
    global
    log 127.0.0.1 local2
    chroot /var/lib/haproxy
    pidfile /var/run/haproxy.pid
    maxconn 4000
    user haproxy
    group haproxy
    stats socket /var/run/haproxy.sock mode 660 level admin
    daemon
    defaults
    mode http
    log global
    option httplog
    option dontlognull
    retries 3
    timeout connect 5s
    timeout client 30s
    timeout server 30s
    timeout http-request 10s
    frontend web_front
    bind *:80
    default_backend web_servers
    backend web_servers
    balance roundrobin
    option httpchk GET /
    server web1 10.0.0.11:80 check
    server web2 10.0.0.12:80 check

    几个要点:

    • mode http 表示工作在七层(HTTP),能解析 HTTP 头;改成 mode tcp 则是四层透传,适合数据库、SMTP 等非 HTTP 协议。
    • balance roundrobin 按顺序轮流分发请求。如果后端处理时长差异较大,改用 balance leastconn 更合适——它会把新连接交给当前连接数最少的后端。
    • server web1 10.0.0.11:80 check 中的 check 启用健康检查;HAProxy 会定期探测该后端,失败后自动摘除,恢复后再加回。
    • option httpchk GET / 把健康检查从默认的 TCP 探测升级为 HTTP 探测,向 / 发起 GET 请求,只有返回 2xx/3xx 才算健康。生产环境建议指向一个专门的健康检查路径(如 /healthz)。

    HAProxy 自带一个实时统计页面,能看到每台后端的状态、流量和会话数。在配置中追加一个 listen 段(或写在某个 frontend 里):

    追加到 /etc/haproxy/haproxy.cfg
    listen stats
    bind *:8404
    stats enable
    stats uri /haproxy?stats
    stats auth admin:password
    stats refresh 10s

    保存后访问 http://<负载均衡器IP>:8404/haproxy?stats,输入用户名 admin、密码 password 即可查看。

    每次修改后,先校验语法再重启,避免把服务改坏:

    校验配置文件
    $ sudo haproxy -c -f /etc/haproxy/haproxy.cfg
    Configuration file is valid

    如果有错误,输出会直接指出出错的行号和原因,按提示修正即可。

    EL 系统默认启用 SELinux。HAProxy 运行在 haproxy_t 域下,默认只允许连接一组常见端口。如果你的后端使用非标准端口,连接会被 SELinux 拒绝,表现为后端始终 down 而网络本身却是通的。

    打开布尔值,允许 HAProxy 连接任意端口:

    允许 HAProxy 连接任意后端端口
    $ sudo setsebool -P haproxy_connect_any on

    放行 HTTP/HTTPS 端口,让客户端能访问到负载均衡器:

    开放 80 与 443
    $ sudo firewall-cmd --permanent --add-service=http
    $ sudo firewall-cmd --permanent --add-service=https
    $ sudo firewall-cmd --reload

    如果统计页面用了 8404,再放行该端口:

    放行统计页面端口
    $ sudo firewall-cmd --permanent --add-port=8404/tcp
    $ sudo firewall-cmd --reload
    启动并设置开机自启
    $ sudo systemctl enable --now haproxy

    查看状态:

    查看运行状态
    $ sudo systemctl status haproxy

    之后每次改完配置,先 haproxy -c -f 校验,再 sudo systemctl reload haproxy 平滑重载(reload 不会中断已有连接)。

    让 HAProxy 直接终止 TLS(在负载均衡器上解密,再以明文转发给后端),客户端只与 HAProxy 建立加密连接。

    1. 准备证书。HAProxy 要求把完整证书链与私钥合并到同一个 .pem 文件里(顺序为证书 + 中间证书 + 私钥):

      合并 fullchain 与私钥
      $ sudo mkdir -p /etc/haproxy/certs
      $ sudo bash -c 'cat fullchain.pem privkey.pem > /etc/haproxy/certs/site.pem'
      $ sudo chmod 600 /etc/haproxy/certs/site.pem
    2. 在 bind 上启用 TLS,并把 80 端口的请求跳转到 HTTPS:

      /etc/haproxy/haproxy.cfg
      frontend web_front
      bind *:80
      bind *:443 ssl crt /etc/haproxy/certs/site.pem
      # 非加密访问一律 301 跳转到 HTTPS
      redirect scheme https code 301 if !{ ssl_fc }
      default_backend web_servers

      ssl_fc 用来判断当前连接是否走了 TLS;!{ ssl_fc } 即”明文请求”,对其执行 redirect scheme https。

    3. 校验并重载:

      校验后重载
      $ sudo haproxy -c -f /etc/haproxy/haproxy.cfg
      $ sudo systemctl reload haproxy

    单台 HAProxy 仍然是单点故障。生产环境通常部署两台 HAProxy,用 Keepalived 在它们之间漂移一个虚拟 IP(VIP):客户端只访问 VIP,主节点宕机时 VIP 自动切换到备节点,实现负载均衡器自身的冗余。

    具体的 Keepalived + VIP 配置、健康检查脚本与脑裂处理,参见 高可用基础。

    这是最常见的报错,几乎都意味着该 backend 没有可用的后端服务器:所有 server 都处于 down 状态,或健康检查全部失败。排查:

    查看后端健康状态
    $ echo "show servers state" | sudo socat stdio /var/run/haproxy.sock

    这条命令依赖上面 global 段里配置的 stats socket;socat 来自 EPEL,用 sudo dnf install socat 安装。更直观的方式是打开统计页面,看哪几台是红色(DOWN)。常见原因:后端服务没起、防火墙挡了健康检查、option httpchk 指向的路径返回了非 2xx/3xx,或后端用非标准端口被 SELinux 拦截(见上文 haproxy_connect_any)。

    • 绑不上 443:先确认证书文件存在且包含私钥,haproxy -c -f 会报 unable to load SSL certificate。再确认权限可读。如日志显示权限被拒,多半是 SELinux 上下文问题,可用 sudo restorecon -Rv /etc/haproxy/ 修复。
    • 后端连接被拒:后端用非标准端口时务必执行 sudo setsebool -P haproxy_connect_any on,否则 SELinux 会静默拒绝连接。

    依次检查:listen stats 段是否写了 stats enable;防火墙是否放行了对应端口(如 8404/tcp);访问的 URL 是否与 stats uri 完全一致(本文是 /haproxy?stats);以及用户名密码是否与 stats auth 匹配。

    启动失败时第一时间运行:

    校验并定位错误
    $ sudo haproxy -c -f /etc/haproxy/haproxy.cfg

    输出会标明出错的行号与原因。也可以查看 journal 获取启动失败的细节:

    查看服务日志
    $ sudo journalctl -u haproxy -n 50 --no-pager