一、概述
1.1 背景介绍
在负载均衡领域,HAProxy 一直被许多工程师视为“瑞士军刀”般的存在。从 1.4 版本到如今的 3.0 版本,它从一个单纯的 TCP/HTTP 代理,逐步演变为支持 QUIC、HTTP/3 等现代协议的先进负载均衡器。
很多人提到负载均衡首先想到 Nginx,但在纯粹的代理转发场景中,HAProxy 在性能与功能细粒度控制上往往更胜一筹。根据在一些电商平台的实际对比测试,在同等硬件条件下,HAProxy 的 QPS 通常比 Nginx 高出 15-20%,并且在高并发时 CPU 占用率更低。
HAProxy 的核心优势在于其设计的专注性。它不像 Nginx 需要兼顾 Web 服务器功能,其所有设计都围绕“如何更高效地转发请求”这一核心目标。这种专注带来了更直观的配置和更极致的性能表现。
1.2 技术特点
HAProxy 3.0 相比早期版本有几个重要的技术更新:
原生 QUIC/HTTP3 支持:现在无需依赖第三方补丁即可使用。虽然目前仍标记为实验性功能,但在测试环境中已表现出良好的稳定性。
成熟的多线程架构:从 2.x 版本引入的多线程模型在 3.0 中已趋于稳定,以往令人担忧的锁竞争问题基本得到解决,nbthread 参数现在可以放心使用。
增强的运行时 API:通过 Runtime API 可以实现后端服务器的热更新,无需重启服务。这在微服务架构下尤其实用,动态管理后端节点变得更加便捷。
优化的内存管理:新的内存池机制使长连接场景下的内存占用更加稳定,有效缓解了内存缓慢增长的问题。
对于网络核心参数的调优是保障 HAProxy 高性能的基础。
1.3 适用场景
基于实践经验,HAProxy 最适合以下场景:
- API 网关:需要精细流量控制、限流、熔断的场景
- 微服务入口:支持服务发现集成与动态后端管理
- 数据库代理:实现 MySQL/PostgreSQL 读写分离与连接池管理
- WebSocket 长连接:具备稳定的长连接保持能力
- 高性能 HTTP 代理:追求极致转发性能的场景
需要注意的是,HAProxy 不太适合需要复杂 URL 重写或静态文件服务的场景,这些任务交给 Nginx 更为合适。
1.4 环境要求
| 组件 |
版本 |
说明 |
| HAProxy |
3.0.5 |
2025年1月稳定版 |
| 操作系统 |
Rocky Linux 9.3 / Ubuntu 24.04 LTS |
推荐使用 Rocky Linux |
| 内核版本 |
5.14+ |
需要支持 io_uring |
| CPU |
4核+ |
生产环境建议 8核起步 |
| 内存 |
4GB+ |
根据连接数调整 |
| GCC |
12+ |
编译安装需要 |
| OpenSSL |
3.0+ |
QUIC 支持需要 |
二、详细步骤
2.1 准备工作
系统优化
在安装 HAProxy 之前,建议先对系统内核参数进行调优。这些参数在高并发场景下至关重要,能够避免许多潜在的性能问题。
# /etc/sysctl.d/99-haproxy.conf
# 文件描述符相关
fs.file-max = 2097152
fs.nr_open = 2097152
# 网络核心参数
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
# TCP 参数优化
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.ip_local_port_range = 1024 65535
# 开启 TCP Fast Open
net.ipv4.tcp_fastopen = 3
# 连接追踪(如果用 iptables)
net.netfilter.nf_conntrack_max = 1048576
应用配置:
sysctl -p /etc/sysctl.d/99-haproxy.conf
同时需要调整进程资源限制:
# /etc/security/limits.d/99-haproxy.conf
haproxy soft nofile 1048576
haproxy hard nofile 1048576
haproxy soft nproc 65535
haproxy hard nproc 65535
安装 HAProxy 3.0
对于 Rocky Linux 9,官方仓库的 HAProxy 版本可能较旧,建议从源码编译或使用官方提供的仓库。
方法一:官方仓库安装(推荐)
# 添加 HAProxy 官方仓库
dnf install -y epel-release
dnf copr enable -y bors/haproxy
# 安装 HAProxy 3.0
dnf install -y haproxy30
方法二:源码编译(追求极致性能)
# 安装依赖
dnf install -y gcc make pcre2-devel openssl-devel systemd-devel \
lua-devel readline-devel zlib-devel
# 下载源码
cd /usr/local/src
wget https://www.haproxy.org/download/3.0/src/haproxy-3.0.5.tar.gz
tar xzf haproxy-3.0.5.tar.gz
cd haproxy-3.0.5
# 编译参数说明:
# TARGET=linux-glibc: 使用 glibc
# USE_OPENSSL=1: 启用 SSL 支持
# USE_PCRE2=1: 使用 PCRE2 正则库
# USE_SYSTEMD=1: 启用 systemd 集成
# USE_LUA=1: 启用 Lua 脚本支持
# USE_QUIC=1: 启用 QUIC/HTTP3(实验性)
# USE_PROMEX=1: 启用 Prometheus 导出器
make -j$(nproc) TARGET=linux-glibc \
USE_OPENSSL=1 USE_PCRE2=1 USE_SYSTEMD=1 \
USE_LUA=1 USE_QUIC=1 USE_PROMEX=1 \
USE_THREAD=1
make install PREFIX=/usr/local/haproxy
创建 systemd 服务文件:
# /etc/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/haproxy
ExecStartPre=/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/local/haproxy/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Restart=always
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
2.2 核心配置
HAProxy 的配置文件逻辑清晰,主要分为四个部分:global(全局)、defaults(默认)、frontend(前端)、backend(后端)。理解这个结构是掌握 HAProxy 配置的关键。
全局配置
# /etc/haproxy/haproxy.cfg
global
# 日志配置 - 发送到本地 rsyslog
log /dev/log local0 info
log /dev/log local1 notice
# 运行身份
user haproxy
group haproxy
# 后台运行
daemon
# 多线程配置 - 关键参数
# nbthread 建议设置为 CPU 核心数,但不超过 64
nbthread 8
# CPU 绑定 - 减少上下文切换
cpu-map auto:1/1-8 0-7
# 最大连接数 - 根据内存调整
# 每个连接大约占用 32KB 内存
maxconn 100000
# SSL 配置
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
# 运行时 API - 用于动态管理
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
# 性能调优
tune.ssl.default-dh-param 2048
tune.bufsize 32768
tune.maxrewrite 1024
tune.http.maxhdr 128
# Lua 脚本路径
lua-load /etc/haproxy/lua/init.lua
默认配置
defaults
# 工作模式:http 或 tcp
mode http
# 继承全局日志配置
log global
# 记录 HTTP 请求日志
option httplog
# 不记录空连接
option dontlognull
# 启用 HTTP 连接关闭
option http-server-close
# 转发客户端 IP
option forwardfor except 127.0.0.0/8
# 后端服务器健康检查失败时重新派发
option redispatch
retries 3
# 超时配置 - 这些值是我们生产环境调优后的结果
timeout connect 5s # 连接后端超时
timeout client 60s # 客户端超时
timeout server 60s # 服务端超时
timeout http-request 10s # HTTP 请求超时
timeout http-keep-alive 10s # Keep-Alive 超时
timeout queue 30s # 队列等待超时
timeout check 5s # 健康检查超时
# 错误文件
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
前端配置
# HTTP 前端 - 80 端口
frontend http_front
bind *:80
# 定义 ACL 规则
acl is_api path_beg /api/
acl is_static path_end .css .js .png .jpg .gif .ico
acl is_websocket hdr(Upgrade) -i WebSocket
# 根据 Host 头分流
acl host_app1 hdr(host) -i app1.example.com
acl host_app2 hdr(host) -i app2.example.com
# 限流 ACL - 每个 IP 每秒最多 100 个请求
stick-table type ip size 100k expire 30s store http_req_rate(10s)
acl is_abuse sc_http_req_rate(0) gt 100
http-request deny deny_status 429 if is_abuse
http-request track-sc0 src
# 添加请求头
http-request set-header X-Forwarded-Proto http
http-request set-header X-Real-IP %[src]
# 路由规则
use_backend api_servers if is_api
use_backend static_servers if is_static
use_backend ws_servers if is_websocket
use_backend app1_servers if host_app1
use_backend app2_servers if host_app2
# 默认后端
default_backend web_servers
# HTTPS 前端 - 443 端口
frontend https_front
# 绑定 443 端口,启用 SSL
bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
# HTTP/2 相关配置
http-request set-header X-Forwarded-Proto https
# HSTS 头
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"
# 复用 HTTP 前端的 ACL 和路由
acl is_api path_beg /api/
use_backend api_servers if is_api
default_backend web_servers
后端配置
# Web 服务器后端
backend web_servers
# 负载均衡算法
balance roundrobin
# 会话保持 - 基于 cookie
cookie SERVERID insert indirect nocache
# HTTP 健康检查
option httpchk GET /health HTTP/1.1\r\nHost:\ localhost
http-check expect status 200
# 后端服务器列表
# weight: 权重
# check: 启用健康检查
# inter: 检查间隔
# fall: 连续失败次数标记为 down
# rise: 连续成功次数标记为 up
server web1 192.168.1.11:8080 weight 100 cookie web1 check inter 3s fall 3 rise 2
server web2 192.168.1.12:8080 weight 100 cookie web2 check inter 3s fall 3 rise 2
server web3 192.168.1.13:8080 weight 100 cookie web3 check inter 3s fall 3 rise 2
# 备用服务器 - 所有主服务器 down 时启用
server web_backup 192.168.1.20:8080 backup
# API 服务器后端
backend api_servers
balance leastconn # API 适合用最少连接算法
option httpchk GET /api/health HTTP/1.1\r\nHost:\ localhost
http-check expect status 200
# 连接复用 - 减少后端连接数
http-reuse safe
# 重试配置
retry-on conn-failure empty-response response-timeout
server api1 192.168.1.21:3000 check inter 2s fall 2 rise 2 maxconn 1000
server api2 192.168.1.22:3000 check inter 2s fall 2 rise 2 maxconn 1000
# WebSocket 后端
backend ws_servers
balance source # WebSocket 需要会话保持
# WebSocket 超时要设长一些
timeout tunnel 3600s
timeout server 3600s
server ws1 192.168.1.31:8080 check
server ws2 192.168.1.32:8080 check
# 静态资源后端
backend static_servers
balance roundrobin
# 静态资源可以开启压缩
compression algo gzip
compression type text/html text/css text/javascript application/javascript
# 缓存头
http-response set-header Cache-Control "public, max-age=86400"
server static1 192.168.1.41:80 check
server static2 192.168.1.42:80 check
状态监控页面
# 统计页面 - 生产环境建议限制访问 IP
frontend stats
bind *:8404
mode http
# IP 白名单
acl allowed_ip src 10.0.0.0/8 192.168.0.0/16
http-request deny unless allowed_ip
stats enable
stats uri /stats
stats refresh 10s
stats admin if TRUE
stats auth admin:your_secure_password
# Prometheus 指标导出
http-request use-service prometheus-exporter if { path /metrics }
2.3 启动和验证
# 检查配置语法
haproxy -c -f /etc/haproxy/haproxy.cfg
# 启动服务
systemctl daemon-reload
systemctl enable haproxy
systemctl start haproxy
# 查看状态
systemctl status haproxy
# 查看监听端口
ss -tlnp | grep haproxy
# 测试健康检查
curl -I http://localhost/health
# 查看后端状态
echo “show stat” | socat stdio /run/haproxy/admin.sock
三、示例代码和配置
3.1 完整配置示例
以下是一个来源于某电商平台生产环境的完整配置示例,日均处理请求量约 500 万:
# /etc/haproxy/haproxy.cfg
# 电商平台负载均衡配置 - HAProxy 3.0.5
# 最后更新: 2025-01-07
global
log /dev/log local0 info
user haproxy
group haproxy
daemon
# 8核服务器配置
nbthread 8
cpu-map auto:1/1-8 0-7
maxconn 200000
# SSL 加固
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
ssl-default-bind-options ssl-min-ver TLSv1.2
# 运行时管理
stats socket /run/haproxy/admin.sock mode 660 level admin
# 性能调优
tune.bufsize 32768
tune.http.maxhdr 128
tune.ssl.default-dh-param 2048
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor
option redispatch
retries 3
timeout connect 5s
timeout client 60s
timeout server 60s
timeout http-request 10s
timeout http-keep-alive 30s
timeout queue 30s
# 自定义日志格式
log-format “%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r”
# HTTP 入口
frontend http_in
bind *:80
# 强制跳转 HTTPS
http-request redirect scheme https unless { ssl_fc }
# HTTPS 入口
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1
# 安全头
http-response set-header X-Frame-Options SAMEORIGIN
http-response set-header X-Content-Type-Options nosniff
http-response set-header X-XSS-Protection “1; mode=block”
http-response set-header Strict-Transport-Security “max-age=31536000”
# 限流表
stick-table type ip size 200k expire 30s store http_req_rate(10s),conn_cur
# 限流规则:单 IP 每 10 秒最多 200 请求,最多 50 并发
acl is_rate_limited sc_http_req_rate(0) gt 200
acl is_conn_limited sc_conn_cur(0) gt 50
http-request track-sc0 src
http-request deny deny_status 429 if is_rate_limited
http-request deny deny_status 429 if is_conn_limited
# ACL 定义
acl is_api path_beg /api/
acl is_admin path_beg /admin/
acl is_static path_end .css .js .png .jpg .jpeg .gif .ico .woff .woff2
acl is_search path_beg /search/
# 管理后台限制 IP
acl admin_ip src 10.10.0.0/16
http-request deny if is_admin !admin_ip
# 路由
use_backend api_backend if is_api
use_backend static_backend if is_static
use_backend search_backend if is_search
default_backend web_backend
# Web 后端 - 主站页面
backend web_backend
balance roundrobin
cookie WEBID insert indirect nocache httponly secure
option httpchk GET /health HTTP/1.1\r\nHost:\ localhost
http-check expect status 200
http-reuse safe
server web01 10.10.1.11:8080 weight 100 cookie s1 check inter 3s fall 3 rise 2
server web02 10.10.1.12:8080 weight 100 cookie s2 check inter 3s fall 3 rise 2
server web03 10.10.1.13:8080 weight 100 cookie s3 check inter 3s fall 3 rise 2
server web04 10.10.1.14:8080 weight 100 cookie s4 check inter 3s fall 3 rise 2
# API 后端 - 接口服务
backend api_backend
balance leastconn
option httpchk GET /api/health HTTP/1.1\r\nHost:\ localhost
http-check expect status 200
http-reuse aggressive
retry-on conn-failure empty-response response-timeout 502 503 504
# 单服务器最大连接数限制,防止雪崩
server api01 10.10.2.11:3000 check inter 2s fall 2 rise 2 maxconn 2000
server api02 10.10.2.12:3000 check inter 2s fall 2 rise 2 maxconn 2000
server api03 10.10.2.13:3000 check inter 2s fall 2 rise 2 maxconn 2000
server api04 10.10.2.14:3000 check inter 2s fall 2 rise 2 maxconn 2000
# 静态资源后端
backend static_backend
balance roundrobin
compression algo gzip
compression type text/css text/javascript application/javascript application/json
http-response set-header Cache-Control “public, max-age=604800”
server static01 10.10.3.11:80 check
server static02 10.10.3.12:80 check
# 搜索服务后端
backend search_backend
balance roundrobin
option httpchk GET /search/health HTTP/1.1\r\nHost:\ localhost
http-check expect status 200
timeout server 30s # 搜索服务响应可能较慢
server search01 10.10.4.11:9200 check inter 5s fall 3 rise 2
server search02 10.10.4.12:9200 check inter 5s fall 3 rise 2
# 监控页面
frontend stats
bind *:8404
mode http
acl internal_net src 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
http-request deny unless internal_net
stats enable
stats uri /stats
stats refresh 5s
stats admin if TRUE
stats auth admin:Ecm@2025$Prod
http-request use-service prometheus-exporter if { path /metrics }
3.2 实际应用案例
案例一:灰度发布配置
在进行 A/B 测试时,需要将 10% 的流量定向到新版本服务,配置如下:
backend web_backend
balance roundrobin
# 灰度发布:10% 流量到新版本
# 使用 ACL 基于 cookie 或随机数分流
acl is_canary rand(100) lt 10
acl has_canary_cookie req.cook(canary) -m found
# 设置灰度 cookie
http-response set-header Set-Cookie “canary=1; Path=/; Max-Age=3600” if is_canary !has_canary_cookie
use-server canary01 if is_canary
use-server canary01 if has_canary_cookie
server web01 10.10.1.11:8080 check
server web02 10.10.1.12:8080 check
server canary01 10.10.1.21:8080 check weight 0 # weight=0 不参与正常轮询
案例二:MySQL 读写分离
HAProxy 也可用作数据库代理,实现 MySQL 读写分离,这通常需要与 数据库 的健康检查机制配合。
# MySQL 代理配置
frontend mysql_front
bind *:3306
mode tcp
default_backend mysql_write
frontend mysql_read_front
bind *:3307
mode tcp
default_backend mysql_read
backend mysql_write
mode tcp
balance first # 写操作只发到第一个可用节点(主库)
option mysql-check user haproxy
server mysql_master 10.10.5.11:3306 check inter 3s fall 3 rise 2
backend mysql_read
mode tcp
balance leastconn
option mysql-check user haproxy
server mysql_slave1 10.10.5.12:3306 check inter 3s fall 3 rise 2 weight 100
server mysql_slave2 10.10.5.13:3306 check inter 3s fall 3 rise 2 weight 100
# 主库作为读的备用
server mysql_master 10.10.5.11:3306 check inter 3s fall 3 rise 2 weight 50 backup
案例三:基于请求头的 A/B 测试
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/
# 检测 A/B 测试标识
acl ab_test_v2 hdr(X-AB-Test) -i v2
acl ab_test_v2 req.cook(ab_version) v2
use_backend web_v2 if ab_test_v2
default_backend web_v1
backend web_v1
balance roundrobin
server v1_01 10.10.1.11:8080 check
server v1_02 10.10.1.12:8080 check
backend web_v2
balance roundrobin
server v2_01 10.10.2.11:8080 check
server v2_02 10.10.2.12:8080 check
四、最佳实践和注意事项
4.1 最佳实践
1. 健康检查优化
避免使用简单的 TCP 端口检查,应使用 HTTP 检查并尽可能验证业务逻辑:
# 基础健康检查
option httpchk GET /health HTTP/1.1\r\nHost:\ localhost
http-check expect status 200
# 深层次健康检查 - 验证关键依赖
http-check connect
http-check send meth GET uri /health/deep ver HTTP/1.1 hdr Host localhost
http-check expect rstatus ^2
2. 连接复用策略
根据后端服务的实际情况选择合适的连接复用策略:
# 安全模式 - 只复用空闲连接
http-reuse safe
# 激进模式 - 复用所有连接(需确保后端支持)
http-reuse aggressive
# 对于 HTTP/2 后端
http-reuse always
3. 优雅下线
在移除后端服务器前,应先将其设置为 drain 模式,等待现有连接处理完毕:
# 通过 Runtime API 设置
echo “set server web_backend/web01 state drain” | socat stdio /run/haproxy/admin.sock
# 等待连接数降为 0
echo “show stat” | socat stdio /run/haproxy/admin.sock | grep web01
# 确认后下线
echo “set server web_backend/web01 state maint” | socat stdio /run/haproxy/admin.sock
4. 日志优化
默认日志信息有限,建议采用自定义 JSON 格式日志以便后续分析:
log-format ‘{“time”:”%t”,”client”:”%ci”,”backend”:”%b”,”server”:”%s”,”status”:%ST,”bytes”:%B,”time_total”:%Ta,”time_connect”:%Tc,”time_response”:%Tr,”retries”:%rc,”request”:”%r”}’
4.2 注意事项
| 错误类型 |
现象 |
原因 |
解决方案 |
| 502 Bad Gateway |
间歇性出现 |
后端响应超时 |
增加 timeout server,检查后端性能 |
| 503 Service Unavailable |
所有请求失败 |
所有后端都 down 了 |
检查健康检查配置,确认后端服务状态 |
| 连接数耗尽 |
新请求被拒绝 |
maxconn 设置太小 |
增加 maxconn,优化后端处理速度 |
| Cookie 丢失 |
会话不保持 |
Cookie 配置错误 |
检查 cookie 配置,注意 secure 属性 |
| SSL 握手失败 |
HTTPS 无法访问 |
证书链不完整 |
检查证书链,确保包含中间证书 |
| 内存持续增长 |
进程内存越来越大 |
长连接泄露 |
检查 timeout tunnel,升级到最新版本 |
| CPU 单核跑满 |
性能不理想 |
没开多线程 |
配置 nbthread 参数 |
经验分享
线上曾出现大量 502 错误,排查后发现是后端服务处理某些大请求时超过了默认的 30 秒超时。调整 timeout server 参数后问题解决。关键教训是:超时时间必须根据实际业务逻辑设定,不能使用一刀切的默认值。
另一次更棘手的问题是,开启 http-reuse aggressive 后,部分请求出现了数据混淆。最终发现是某个老旧的后端服务不支持 HTTP Keep-Alive 连接复用。因此,任何新配置上线前,都必须在测试环境中进行充分验证。
五、故障排查和监控
5.1 故障排查
查看实时日志
首先配置 rsyslog 将 HAProxy 日志单独存放:
# 配置 rsyslog
cat > /etc/rsyslog.d/haproxy.conf << ‘EOF’
$AddUnixListenSocket /dev/log
# HAProxy 日志单独存放
if $programname startswith ‘haproxy’ then /var/log/haproxy/haproxy.log
& stop
EOF
systemctl restart rsyslog
# 实时查看
tail -f /var/log/haproxy/haproxy.log
使用 Runtime API 排查
Runtime API 是强大的实时排查工具:
# 查看所有后端状态
echo “show stat” | socat stdio /run/haproxy/admin.sock
# 查看当前会话
echo “show sess” | socat stdio /run/haproxy/admin.sock
# 查看错误统计
echo “show errors” | socat stdio /run/haproxy/admin.sock
# 查看后端队列
echo “show pools” | socat stdio /run/haproxy/admin.sock
# 查看服务器详细信息
echo “show servers state” | socat stdio /run/haproxy/admin.sock
常用系统排查命令
# 检查端口监听
ss -tlnp | grep haproxy
# 检查系统总连接数
ss -s
# 检查 TIME_WAIT 连接数量
ss -ant | grep TIME-WAIT | wc -l
# 抓包分析(谨慎使用)
tcpdump -i any port 80 -nn -w haproxy.pcap
5.2 性能监控
Prometheus 集成
HAProxy 3.0 内置了 Prometheus 指标导出器,可以直接通过 /metrics 端点获取监控数据,相关配置与最佳实践可以在 云栈社区的运维板块 找到更多资料。
# haproxy.cfg 中配置
frontend stats
bind *:8404
http-request use-service prometheus-exporter if { path /metrics }
关键监控指标
# 必须监控的指标
haproxy_frontend_current_sessions: 当前活跃会话数
haproxy_frontend_http_requests_total: 请求总数
haproxy_backend_active_servers: 活跃后端数量
haproxy_backend_http_responses_total: 后端响应统计(按状态码)
haproxy_backend_response_time_average_seconds: 平均响应时间
haproxy_server_status: 服务器状态(1=UP, 0=DOWN)
haproxy_server_current_queue: 服务器当前队列长度
# 报警阈值建议
活跃会话数 > maxconn * 0.8: 警告
后端服务器状态变化: 立即报警
5xx 错误率 > 1%: 警告
平均响应时间 > 2s: 警告
Grafana Dashboard
推荐使用 Grafana 官方仪表板 ID: 12693,它提供了 HAProxy 核心指标的可视化。
5.3 备份与恢复
配置备份脚本
建议定期备份配置和证书。
#!/bin/bash
# /usr/local/bin/haproxy-backup.sh
BACKUP_DIR=“/backup/haproxy”
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p ${BACKUP_DIR}
# 备份配置
tar czf ${BACKUP_DIR}/haproxy_config_${DATE}.tar.gz \
/etc/haproxy/ \
/etc/sysctl.d/99-haproxy.conf \
/etc/security/limits.d/99-haproxy.conf
# 备份证书
tar czf ${BACKUP_DIR}/haproxy_certs_${DATE}.tar.gz \
/etc/haproxy/certs/
# 保留最近 30 天的备份
find ${BACKUP_DIR} -type f -mtime +30 -delete
快速恢复流程
# 1. 安装 HAProxy(同版本)
# 2. 恢复配置
tar xzf haproxy_config_${DATE}.tar.gz -C /
tar xzf haproxy_certs_${DATE}.tar.gz -C /
# 3. 验证配置
haproxy -c -f /etc/haproxy/haproxy.cfg
# 4. 启动服务
systemctl start haproxy
六、总结
6.1 技术要点回顾
- HAProxy 3.0 的多线程模型已非常成熟,可在生产环境放心使用。
- 健康检查应基于 HTTP 应用层,而非简单的 TCP 端口检查。
- 所有超时参数必须根据实际业务负载和响应时间进行调整,不可盲目使用默认值。
- Runtime API 是强大的运维工具,掌握后能实现后端服务器的动态管理。
- 自定义日志格式能极大提升后续日志分析与故障排查的效率。
6.2 进阶学习方向
- Lua 脚本扩展:利用 Lua 脚本实现更复杂的流量控制与处理逻辑。
- QUIC/HTTP3:探索并配置下一代网络协议。
- 服务网格集成:学习 HAProxy 在 Kubernetes 及服务网格环境中的部署与应用模式。
- 安全加固:研究如何配置 WAF 规则、DDoS 防护等安全策略。
6.3 参考资料
附录
A. 命令速查表
| 命令 |
说明 |
haproxy -c -f /etc/haproxy/haproxy.cfg |
检查配置语法 |
haproxy -vv |
查看编译选项和版本 |
systemctl reload haproxy |
平滑重载配置 |
echo “show stat” | socat stdio /run/haproxy/admin.sock |
查看统计信息 |
echo “show info” | socat stdio /run/haproxy/admin.sock |
查看进程信息 |
echo “set server backend/server state drain” | socat stdio /run/haproxy/admin.sock |
设置服务器为 drain 模式 |
echo “set server backend/server state maint” | socat stdio /run/haproxy/admin.sock |
设置服务器为维护模式 |
echo “set server backend/server state ready” | socat stdio /run/haproxy/admin.sock |
恢复服务器 |
echo “disable server backend/server” | socat stdio /run/haproxy/admin.sock |
禁用服务器 |
echo “enable server backend/server” | socat stdio /run/haproxy/admin.sock |
启用服务器 |
B. 配置参数详解
| 参数 |
默认值 |
推荐值 |
说明 |
| maxconn |
2000 |
根据内存调整 |
全局最大连接数,每连接约 32KB |
| nbthread |
1 |
CPU 核心数 |
工作线程数,不超过 64 |
| timeout connect |
5s |
5s |
连接后端超时 |
| timeout client |
50s |
60s |
客户端超时 |
| timeout server |
50s |
60s |
服务端超时 |
| timeout http-request |
10s |
10s |
HTTP 请求超时 |
| timeout http-keep-alive |
1s |
10-30s |
Keep-Alive 超时 |
| tune.bufsize |
16384 |
32768 |
缓冲区大小 |
| tune.maxrewrite |
1024 |
1024 |
最大重写空间 |
| tune.http.maxhdr |
101 |
128 |
最大 HTTP 头数量 |
C. 术语表
| 术语 |
解释 |
| Frontend |
前端,接收客户端请求的入口 |
| Backend |
后端,处理请求的服务器组 |
| ACL |
Access Control List,访问控制列表,用于定义匹配规则 |
| Server |
后端服务器节点 |
| Sticky Session |
会话保持,确保同一用户请求发到同一后端 |
| Health Check |
健康检查,定期检测后端服务器状态 |
| Runtime API |
运行时 API,用于动态管理 HAProxy |
| Drain |
排空模式,停止接收新连接但处理完现有连接 |
| Maintenance |
维护模式,完全停止服务 |
| Weight |
权重,用于加权负载均衡 |
更多负载均衡、高可用及系统架构相关的实战经验和配置模板,可以在 云栈社区 的技术论坛中找到。