HAProxy 3.0 企业级负载均衡实战:从单机到高可用集群

HAProxy 3.0 企业级负载均衡实战:从单机到高可用集群

副标题:告别 Nginx 单点瓶颈,用 HAProxy 构建 10 万级并发网关

环境:华为云 ECS(4 节点)| Ubuntu 24.04 LTS | HAProxy 3.0.10 LTS | Keepalived

日期:2026-06-11


目录

  1. [为什么选择 HAProxy?](#为什么选择 HAProxy?)
  2. 架构总览
  3. 环境准备与服务器规划
  4. [源码编译安装 HAProxy 3.0](#源码编译安装 HAProxy 3.0)
  5. 核心配置详解(haproxy.cfg)
  6. [实战场景1:HTTP 负载均衡 + 健康检查](#实战场景1:HTTP 负载均衡 + 健康检查)
  7. [实战场景2:ACL 规则路由(按 URL 分发)](#实战场景2:ACL 规则路由(按 URL 分发))
  8. [实战场景3:Keepalived + HAProxy 高可用](#实战场景3:Keepalived + HAProxy 高可用)
  9. 统计页面与命令行管理
  10. [Prometheus 指标监控](#Prometheus 指标监控)
  11. 负载均衡算法对比
  12. [会话保持(Session Affinity)](#会话保持(Session Affinity))
  13. 生产环境最佳实践
  14. 踩坑记录与排错
  15. 总结与延伸

一、为什么选择 HAProxy?

1.1 HAProxy vs Nginx vs LVS

维度 HAProxy 3.0 Nginx LVS (IPVS)
定位 专业负载均衡器 Web 服务器 + 反向代理 四层负载均衡(内核级)
性能 10 万+ 并发,7 层最优 5 万+ 并发 100 万+ 并发(仅 4 层)
协议支持 TCP + HTTP + gRPC HTTP/HTTPS + WebSocket TCP/UDP(仅 4 层)
健康检查 最丰富(HTTP/TCP/Lua) 基础健康检查 无(需配合 Keepalived)
ACL 规则 强大灵活(支持正则) 基础 location 匹配
会话保持 Cookie / Source IP Cookie / IP Hash 源 IP Hash
统计监控 内置 Web UI + Prometheus 需第三方模块
内存占用 ~11MB ~5MB 内核态,不占用户空间
适用场景 高并发 Web/API 网关 静态资源 + 反向代理 超大流量入口

1.2 HAProxy 核心优势

  • 单机支撑 10 万+ 并发连接(官方测试数据)
  • 毫秒级故障切换(健康检查间隔可设 1s)
  • ACL 规则引擎:实现复杂路由逻辑(按 URL、Header、IP 路由)
  • 内置统计页面:实时查看后端服务器状态、QPS、响应时间
  • Prometheus 原生支持:PromEX 指标导出,零配置接入监控
  • LTS 长期支持:3.0 分支支持到 2029 年 Q2

二、架构总览

2.1 本教程最终架构

复制代码
                    ┌─────────────────────────────────────────┐
                    │           客户端 (Internet)               │
                    └──────────────────┬──────────────────────┘
                                       │
                              ┌────────▼────────┐
                              │   VIP 浮动 IP    │
                              │  192.168.0.200  │
                              └───────┬─────────┘
                                      │
                   ┌──────────────────┼──────────────────┐
                   │                  │                   │
          ┌────────▼───────┐          │          ┌───────▼────────┐
          │  HAProxy 主     │  VRRP   │          │  HAProxy 备     │
          │  (haproxy-01)  │◄────────►│          │  (haproxy-02)   │
          │  121.36.66.88  │ 心跳检测  │          │  1.92.127.225  │
          │  priority=100  │          │          │  priority=90    │
          └────────┬───────┘          │          └───────┬────────┘
                   │                  │                   │
                   │          ┌───────▼───────┐          │
                   │          │  Keepalived    │          │
                   │          │  VRRP 双机热备  │          │
                   │          └───────────────┘          │
                   │                                      │
          ┌────────▼──────────────────────────────────────▼────────┐
          │                   HAProxy 负载分发                      │
          │   frontend (80) → ACL 路由 → backend (roundrobin)      │
          │   stats (1936) → Web 统计页面                           │
          │   promex (8404) → Prometheus 指标                      │
          └────────┬─────────────────────────────────┬─────────────┘
                   │                                 │
          ┌────────▼────────┐               ┌────────▼────────┐
          │   Web-01        │               │   Web-02        │
          │   (ecs-8d39-03) │               │   (ecs-8d39-04) │
          │   192.168.0.171 │               │   192.168.0.167│
          │   Nginx :80     │               │   Nginx :80    │
          └─────────────────┘               └─────────────────┘

2.2 数据流路径

复制代码
客户端 → VIP:80 → HAProxy frontend → ACL 匹配 →
  ├── path_beg /api     → api_back    (leastconn)
  ├── path_beg /static  → static_back (roundrobin)
  ├── path_beg /health  → 直接返回 200
  └── default           → web_back    (roundrobin)

三、环境准备与服务器规划

3.1 服务器清单

角色 主机名 公网 IP 私网 IP 配置 用途
HAProxy 主 ecs-8d39-0001 121.36.66.88 192.168.0.164 2vCPU/4GiB 负载均衡器(MASTER)
HAProxy 备 ecs-8d39-0002 1.92.127.225 192.168.0.19 2vCPU/4GiB 负载均衡器(BACKUP)
后端 Web1 ecs-8d39-0003 120.46.80.157 192.168.0.171 2vCPU/4GiB Nginx Web 服务器
后端 Web2 ecs-8d39-0004 1.92.73.166 192.168.0.167 2vCPU/4GiB Nginx Web 服务器

3.2 系统信息

复制代码
$ hostnamectl
  Operating System: Ubuntu 24.04.4 LTS
            Kernel: Linux 6.8.0-106-generic
       Architecture: x86-64

$ free -h
Mem:           3.3Gi       438Mi       2.7Gi

$ nproc
2

3.3 内网互通验证

bash 复制代码
# haproxy-01 → 其他节点
$ ping -c 2 192.168.0.19     # haproxy-02
64 bytes from 192.168.0.19: icmp_seq=1 ttl=64 time=0.306 ms

$ ping -c 2 192.168.0.171   # web-01
64 bytes from 192.168.0.171: icmp_seq=1 ttl=64 time=3.04 ms

$ ping -c 2 192.168.0.167   # web-02
64 bytes from 192.168.0.167: icmp_seq=1 ttl=64 time=2.73 ms

✅ 四台服务器内网全互通,延迟 < 5ms

3.4 需开放的安全组端口

端口 协议 用途
80 TCP HAProxy HTTP 入口
1936 TCP HAProxy 统计页面
8404 TCP Prometheus 指标端点

四、源码编译安装 HAProxy 3.0

4.1 为什么选择源码编译?

方式 版本 自定义特性 适用场景
apt install 2.x(旧版) ❌ 无法选择 快速测试
源码编译 3.0.10(最新 LTS) ✅ 全特性可选 生产环境推荐

4.2 安装编译依赖

bash 复制代码
sudo apt update
sudo apt install -y build-essential libpcre3-dev libssl-dev libsystemd-dev zlib1g-dev

各依赖包说明

包名 说明 编译选项
build-essential GCC 编译器 + Make 必须
libpcre3-dev Perl 兼容正则表达式 USE_PCRE=1
libssl-dev OpenSSL 加密库 USE_OPENSSL=1
libsystemd-dev systemd 通知集成 USE_SYSTEMD=1
zlib1g-dev gzip 压缩 USE_ZLIB=1

4.3 下载源码

bash 复制代码
# 华为云镜像(国内推荐,速度快 10 倍+)
cd /tmp
wget https://mirrors.huaweicloud.com/haproxy/3.0/src/haproxy-3.0.10.tar.gz

# 验证包大小(完整包 4.6MB)
$ ls -lh haproxy-3.0.10.tar.gz
-rw-r--r-- 1 root root 4.6M Apr 22  2025 haproxy-3.0.10.tar.gz

⚠️ 踩坑 :首次从 haproxy.org 官方下载仅得到 1.3MB 不完整包(海外节点慢),导致 tar 解压失败。务必使用华为镜像!

4.4 编译安装

bash 复制代码
cd /tmp
tar -xzf haproxy-3.0.10.tar.gz
cd haproxy-3.0.10

# 编译(启用所有生产特性)
make TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_PROMEX=1 -j$(nproc)

# 安装到 /usr/local
make install-bin PREFIX=/usr/local

编译选项详解

选项 说明
TARGET=linux-glibc 目标平台为 Linux + glibc
USE_PCRE=1 启用正则表达式支持(ACL 规则需要)
USE_OPENSSL=1 启用 SSL/TLS 终止
USE_ZLIB=1 启用 HTTP 压缩
USE_SYSTEMD=1 启用 systemd 通知(Type=notify)
USE_PROMEX=1 启用 Prometheus 指标导出

4.5 验证安装

bash 复制代码
$ /usr/local/sbin/haproxy -v
HAProxy version 3.0.10-346eb4f 2025/04/22 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2029.

$ /usr/local/sbin/haproxy -vv
Feature list : +ACCEPT4 +CPU_AFFINITY +EPOLL +OPENSSL +PCRE +PROMEX
               +SSL +SYSTEMD +TFO +THREAD +TPROXY +ZLIB
Built with multi-threading support (MAX_TGROUPS=16, MAX_THREADS=256, default=2).
Built with OpenSSL version : OpenSSL 3.0.13 30 Jan 2024

4.6 创建运行环境

bash 复制代码
# 创建系统用户
sudo useradd -r -s /usr/sbin/nologin haproxy

# 创建目录
sudo mkdir -p /etc/haproxy /var/lib/haproxy /run/haproxy /var/log/haproxy

4.7 创建 systemd 服务

ini 复制代码
# /etc/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
Documentation=https://www.haproxy.org/
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
ExecStartPre=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/local/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy/haproxy.pid
ExecReload=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

关键字段解析

字段 说明
Type=notify HAProxy 编译时启用了 USE_SYSTEMD=1,会主动通知 systemd 启动完成
ExecStartPre ... -c -q 启动前先做配置语法检查,-q 安静模式
-Ws 以守护进程 + systemd 通知模式运行
KillMode=mixed 先发 SIGTERM,等超时后 SIGKILL
ExecReload=kill -USR2 优雅重载配置(不断开现有连接)

五、核心配置详解(haproxy.cfg)

5.1 配置文件结构

HAProxy 配置由 4 大段组成:

复制代码
┌────────────────────────────────────────┐
│  global    → 全局参数(进程级)         │
├────────────────────────────────────────┤
│  defaults  → 默认参数(被继承)         │
├────────────────────────────────────────┤
│  frontend  → 前端入口(监听+ACL)      │
├────────────────────────────────────────┤
│  backend   → 后端服务器组              │
└────────────────────────────────────────┘
    还可使用 listen(frontend+backend 合体)

5.2 完整配置文件

haproxy 复制代码
# ================================================================
# HAProxy 3.0.10 企业级负载均衡配置
# 集群: ecs-8d39 | 环境: 生产模拟
# ================================================================

# ─────────────── 全局配置 (global) ───────────────
global
    # 日志输出到 rsyslog(local0 设施)
    log /dev/log local0 info
    log /dev/log local1 notice

    # 最大并发连接数(2vCPU/4GiB 建议值)
    # 每个连接约占 30KB 内存,20000 × 30KB ≈ 600MB
    maxconn 20000

    # 运行用户和组(安全:不以 root 运行)
    user haproxy
    group haproxy

    # 以后台守护进程运行
    daemon

    # 统计 Socket(用于 socat 命令行管理)
    # mode 660: 仅 root/haproxy 组可读写
    # level admin: 允许管理操作(disable/enable server)
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s

    # PID 文件
    pidfile /run/haproxy/haproxy.pid

# ─────────────── 默认配置 (defaults) ───────────────
defaults
    log global
    mode http

    # HTTP 日志格式(记录请求方法/URI/状态码/响应时间)
    option httplog

    # 不记录空连接日志(健康检查会产生大量空连接)
    option dontlognull

    # 不记录健康检查日志(减少日志噪音)
    option http-ignore-probes

    # 连接失败后重试次数
    retries 3

    # ── 超时配置 ──
    timeout connect     5s      # 与后端建立连接的超时
    timeout client      30s     # 客户端空闲超时
    timeout server      30s     # 与后端服务器空闲超时
    timeout http-request 10s    # 完整 HTTP 请求超时(防慢速攻击)
    timeout queue       1m      # 后端满排队等待超时
    timeout tunnel      1h      # WebSocket 隧道超时
    timeout http-keep-alive 10s  # HTTP keep-alive 超时
    timeout check       5s      # 健康检查超时

# ─────────────── 前端: HTTP 入口 ───────────────
frontend http_front
    bind *:80
    mode http

    # 透传客户端真实 IP 到后端
    # 添加 X-Forwarded-For 头(后端日志能看到真实客户端 IP)
    option forwardfor
    http-request set-header X-Forwarded-Proto http

    # ── ACL 规则引擎 ──
    acl is_api     path_beg /api                # URL 以 /api 开头
    acl is_static  path_beg /static /images /css /js  # 静态资源路径
    acl is_health  path_beg /health             # 健康检查路径

    # ── 路由分发 ──
    use_backend api_back     if is_api
    use_backend static_back if is_static

    # 健康检查端点(直接返回 200,不转后端)
    http-request return status 200 content-type text/plain string "HAProxy-OK" if is_health

    # 默认后端(未匹配任何 ACL 规则时使用)
    default_backend web_back

# ─────────────── 后端: Web 集群 (轮询) ───────────────
backend web_back
    mode http
    balance roundrobin

    # HTTP 健康检查
    option httpchk GET /health
    http-check expect status 200

    # 后端服务器定义
    # check: 启用健康检查
    # inter 2s: 每 2 秒检查一次
    # rise 2: 连续 2 次成功标记为 UP
    # fall 3: 连续 3 次失败标记为 DOWN
    server web-01 192.168.0.171:80 check inter 2s rise 2 fall 3
    server web-02 192.168.0.167:80 check inter 2s rise 2 fall 3

# ─────────────── 后端: API 集群 (最少连接) ───────────────
backend api_back
    mode http
    balance leastconn

    option httpchk GET /health
    http-check expect status 200

    server api-01 192.168.0.171:80 check inter 2s rise 2 fall 3
    server api-02 192.168.0.167:80 check inter 2s rise 2 fall 3

# ─────────────── 后端: 静态资源集群 ───────────────
backend static_back
    mode http
    balance roundrobin

    server static-01 192.168.0.171:80 check inter 2s rise 2 fall 3

# ─────────────── 统计页面 (Web UI) ───────────────
listen stats
    bind *:1936
    mode http

    stats enable
    stats uri /haproxy_stats        # 访问路径
    stats realm HAProxy\ Statistics # 认证提示
    stats auth admin:HAProxy@2026   # 用户名:密码
    stats refresh 5s                # 自动刷新间隔
    stats show-legends              # 显示图例
    stats admin if LOCALHOST        # 仅本机可管理操作

# ─────────────── Prometheus 指标端点 ───────────────
frontend promex
    bind *:8404
    mode http

    # 仅允许内网访问指标
    acl is_internal src 192.168.0.0/16 127.0.0.1
    http-request deny if !is_internal

    http-request use-service prometheus-exporter if { path /metrics }
    default_backend stats_back

backend stats_back
    mode http
    server local 127.0.0.1:1936 check

5.3 配置语法检查

bash 复制代码
$ haproxy -c -f /etc/haproxy/haproxy.cfg
Warnings were found.    # ← 仅 WARNING 不影响运行

⚠️ 踩坑nbproc 在 HAProxy 3.0 中已弃用!3.0 自动使用多线程(nbthread),如果配置 nbproc 会报 ALERT


六、实战场景1:HTTP 负载均衡 + 健康检查

6.1 后端服务器准备

在 web-01/web-02 上安装 Nginx 并创建不同标识页面:

bash 复制代码
# web-01 (192.168.0.171)
sudo apt install -y nginx
cat > /var/www/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>Web-01</title></head>
<body style="background:#e8f5e9;font-family:monospace;padding:40px;">
<h1 style="color:#2e7d32;">Web-01 (ecs-8d39-0003)</h1>
<p>Server: 120.46.80.157 / 192.168.0.171</p>
<hr>
<p style="color:#666;">HAProxy Backend Server #1</p>
</body>
</html>
EOF

# 创建健康检查端点
echo "OK from Web-01" > /var/www/html/health
sudo systemctl restart nginx

web-02 同理,改标识为 "Web-02"。

6.2 启动 HAProxy

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl enable haproxy
sudo systemctl start haproxy

# 验证
$ systemctl status haproxy
Active: active (running)

$ ss -tlnp | grep haproxy
LISTEN  0  4096  0.0.0.0:80     0.0.0.0:*  users:(("haproxy",fd=7))
LISTEN  0  4096  0.0.0.0:1936   0.0.0.0:*  users:(("haproxy",fd=8))
LISTEN  0  4096  0.0.0.0:8404   0.0.0.0:*  users:(("haproxy",fd=9))

6.3 验证轮询负载均衡

bash 复制代码
$ for i in 1 2 3 4; do curl -s http://localhost/ | grep -oP 'Web-0[12]'; done
Web-01
Web-02
Web-01
Web-02

✅ 轮询(roundrobin)生效:请求依次分发到 web-01 和 web-02

6.4 验证健康检查(自动剔除故障节点)

bash 复制代码
# [1] 正常状态
$ echo "show stat" | socat stdio /run/haproxy/admin.sock | cut -d',' -f1,2,18 | grep web-0
web_back,web-01,UP
web_back,web-02,UP

# [2] 停掉 web-01 的 Nginx
$ ssh web-01 "sudo systemctl stop nginx"

# [3] 等待 8 秒(inter=2s × fall=3 = 最多 6 秒检测到故障)
$ sleep 8
$ echo "show stat" | socat stdio /run/haproxy/admin.sock | cut -d',' -f1,2,18 | grep web-0
web_back,web-01,DOWN     ← 自动标记为 DOWN
web_back,web-02,UP

# [4] 所有请求自动转到 web-02
$ for i in 1 2 3 4; do curl -s http://localhost/ | grep -oP 'Web-0[12]'; done
Web-02
Web-02
Web-02
Web-02

✅ 故障自动剔除!零中断服务

6.5 恢复故障节点

bash 复制代码
$ ssh web-01 "sudo systemctl start nginx"
$ sleep 6   # 等待 rise=2 次检查通过

$ echo "show stat" | socat stdio /run/haproxy/admin.sock | cut -d',' -f1,2,18 | grep web-0
web_back,web-01,UP     ← 自动恢复
web_back,web-02,UP

# 轮询恢复正常
$ for i in 1 2 3 4; do curl -s http://localhost/ | grep -oP 'Web-0[12]'; done
Web-01
Web-02
Web-01
Web-02

6.6 健康检查参数详解

复制代码
server web-01 192.168.0.171:80 check inter 2s rise 2 fall 3
                                   │         │      │     │
                                   │         │      │     └─ 连续3次失败→DOWN
                                   │         │     └───── 连续2次成功→UP
                                   │         └─────────── 检查间隔2秒
                                   └───────────────────── 启用健康检查

七、实战场景2:ACL 规则路由(按 URL 分发)

7.1 ACL 路由架构

复制代码
                  客户端请求
                      │
              ┌───────▼───────┐
              │  HAProxy ACL  │
              │  规则引擎      │
              └───────┬───────┘
                      │
          ┌───────────┼───────────┐
          │           │           │
    /api/*        /static/*    其他路径
          │           │           │
    ┌─────▼─────┐ ┌──▼────┐ ┌───▼────┐
    │ api_back  │ │static │ │web_back│
    │ leastconn │ │round- │ │round-  │
    │           │ │robin  │ │robin   │
    └───────────┘ └───────┘ └────────┘

7.2 ACL 规则详解

规则 匹配条件 路由目标
path_beg /api URL 以 /api 开头 api_back(leastconn)
path_beg /static URL 以 /static 开头 static_back(roundrobin)
path_beg /health 健康检查路径 直接返回 200
默认 未匹配任何规则 web_back(roundrobin)

7.3 验证 ACL 路由

bash 复制代码
# /api 路径 → api_back
$ curl -s http://localhost/api/test
{"service":"api","server":"web-02","status":"ok"}

# /static 路径 → static_back
$ curl -s http://localhost/static/test
static-content from web-01

# /health 路径 → HAProxy 直接返回
$ curl -s http://localhost/health
HAProxy-OK

# 默认路径 → web_back
$ curl -s http://localhost/ | grep -oP 'Web-0[12]'
Web-01

7.4 ACL 高级用法

haproxy 复制代码
# 按 Host 头路由(虚拟主机)
acl is_blog hdr(host) -i blog.example.com
use_backend blog_back if is_blog

# 按 IP 白名单限制
acl is_trusted src 192.168.1.0/24
http-request deny if !is_trusted

# 按 User-Agent 限流(反爬虫)
acl is_bot hdr_sub(User-Agent) -i bot crawler
http-request tarpit if is_bot

# 按请求方法限制
acl is_get method GET
http-request deny if !is_get

# 正则匹配 URL
acl is_old_url path_regex ^/old/.*$
http-request redirect prefix /new/ code 301 if is_old_url

八、实战场景3:Keepalived + HAProxy 高可用

8.1 高可用架构

复制代码
           客户端
              │
     VIP: 192.168.0.200(浮动 IP)
              │
   ┌──────────┼──────────┐
   │          │           │
┌──▼─────┐  VRRP    ┌───▼────┐
│ MASTER │◄────────►│ BACKUP │
│ 优先100 │  心跳检测  │ 优先90 │
│:80/1936│  每1秒    │:80/1936│
└──┬─────┘          └───┬────┘
   │                    │
   │   chk_haproxy     │
   │   每2秒检查进程    │
   │   失败→优先级-30   │
   │                    │
   ▼                    ▼
  web-01             web-02

8.2 安装 Keepalived

bash 复制代码
# 在 haproxy-01 和 haproxy-02 上执行
sudo apt install -y keepalived

8.3 健康检查脚本

bash 复制代码
# /etc/keepalived/chk_haproxy
#!/bin/bash
# 检查 HAProxy 进程是否存活
if ! pgrep -x haproxy > /dev/null; then
    echo "$(date): HAProxy is down, stopping keepalived" >> /var/log/keepalived-haproxy.log
    systemctl stop keepalived    # 停掉自己,让备节点接管
    exit 1
fi
exit 0

关键逻辑:HAProxy 进程不在 → 停掉 Keepalived → VIP 漂移到备节点

8.4 主节点配置

bash 复制代码
# /etc/keepalived/keepalived.conf (MASTER)
global_defs {
    router_id HAProxy_MASTER
    vrrp_skip_check_adv_addr
    vrrp_garp_interval 0.001
    vrrp_gna_interval 0.001
}

vrrp_script chk_haproxy {
    script "/etc/keepalived/chk_haproxy"
    interval 2        # 每 2 秒检查一次
    weight -30        # 检查失败时优先级减 30(100-30=70 < 90,备节点抢占)
    fall 2            # 连续 2 次失败才判定
    rise 2            # 连续 2 次成功才恢复
}

vrrp_instance VI_1 {
    state MASTER              # 主节点标识
    interface eth0            # 网卡名称
    virtual_router_id 51      # VRID(主备必须一致!)
    priority 100              # 优先级(主 > 备)
    advert_int 1              # VRRP 通告间隔(秒)

    authentication {
        auth_type PASS
        auth_pass HAProxy@2026    # 认证密码(主备一致,最长8字符)
    }

    virtual_ipaddress {
        192.168.0.200/24 dev eth0  # VIP 地址
    }

    track_script {
        chk_haproxy               # 跟踪 HAProxy 健康检查
    }

    notify_master "/etc/keepalived/notify.sh MASTER"
    notify_backup "/etc/keepalived/notify.sh BACKUP"
    notify_fault  "/etc/keepalived/notify.sh FAULT"
}

8.5 备节点配置

bash 复制代码
# /etc/keepalived/keepalived.conf (BACKUP)
# 仅修改三处:router_id、state、priority

global_defs {
    router_id HAProxy_BACKUP    # ← 不同
    vrrp_skip_check_adv_addr
    vrrp_garp_interval 0.001
    vrrp_gna_interval 0.001
}

vrrp_script chk_haproxy {
    script "/etc/keepalived/chk_haproxy"
    interval 2
    weight -30
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP               # ← 不同:BACKUP
    interface eth0
    virtual_router_id 51
    priority 90                # ← 不同:低于主节点
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass HAProxy@2026
    }

    virtual_ipaddress {
        192.168.0.200/24 dev eth0
    }

    track_script {
        chk_haproxy
    }
}

8.6 主备配置差异对比

参数 主节点 (MASTER) 备节点 (BACKUP)
router_id HAProxy_MASTER HAProxy_BACKUP
state MASTER BACKUP
priority 100 90
virtual_router_id 51 51(必须一致)
auth_pass HAProxy@2026 HAProxy@2026(必须一致)

8.7 VIP 漂移实测

复制代码
[1] 正常状态 - VIP 在主节点
$ ip addr show eth0 | grep '192.168.0.200'
    inet 192.168.0.200/24 scope global secondary eth0

[2] 停掉主节点 HAProxy → 触发 VIP 漂移
$ systemctl stop haproxy

[3] 等待 6 秒 → VIP 漂移到备节点
$ ssh haproxy-02 "ip addr show eth0 | grep '192.168.0.200'"
    inet 192.168.0.200/24 scope global secondary eth0

[4] 通过 VIP 访问 → 服务正常
$ curl -s http://192.168.0.200/ | grep -oP 'Web-0[12]'
Web-02
Web-02

[5] 恢复主节点 → VIP 自动回漂
$ systemctl start haproxy && systemctl start keepalived
$ ip addr show eth0 | grep '192.168.0.200'
    inet 192.168.0.200/24 scope global secondary eth0

✅ VIP 漂移全流程:MASTER DOWN → BACKUP 接管 → MASTER 恢复 → VIP 回漂


九、统计页面与命令行管理

9.1 Web 统计页面

访问地址:http://121.36.66.88:1936/haproxy_stats

  • 用户名:admin
  • 密码:HAProxy@2026
  • 自动刷新:5 秒

统计页面可查看:

  • 后端服务器状态(UP/DOWN)
  • 当前活跃连接数、QPS
  • 响应时间(平均/最大)
  • 错误率(4xx/5xx)
  • 会话速率、数据传输量

9.2 命令行管理(socat)

bash 复制代码
# 安装 socat
sudo apt install -y socat

# 查看后端状态
$ echo "show stat" | socat stdio /run/haproxy/admin.sock | cut -d',' -f1,2,18
# pxname,svname,status
web_back,web-01,UP
web_back,web-02,UP

# 临时禁用后端(维护模式)
$ echo "disable server web_back/web-01" | socat stdio /run/haproxy/admin.sock

# 启用后端
$ echo "enable server web_back/web-01" | socat stdio /run/haproxy/admin.sock

# 查看所有服务器详细信息
$ echo "show servers state" | socat stdio /run/haproxy/admin.sock

# 优雅重载配置(不断开现有连接)
$ sudo haproxy -f /etc/haproxy/haproxy.cfg -sf $(pidof haproxy)

十、Prometheus 指标监控

10.1 PromEX 指标端点

HAProxy 3.0 内置 Prometheus Exporter(编译时 USE_PROMEX=1):

bash 复制代码
$ curl -s http://127.0.0.1:8404/metrics | head -10
# HELP haproxy_process_nbthread Number of started threads
# TYPE haproxy_process_nbthread gauge
haproxy_process_nbthread 2

# HELP haproxy_process_uptime_seconds How long ago this worker was started
# TYPE haproxy_process_uptime_seconds gauge
haproxy_process_uptime_seconds 3600

10.2 关键指标

指标 说明 告警建议
haproxy_frontend_current_sessions 当前活跃会话数 > maxconn × 80%
haproxy_backend_current_sessions 后端活跃会话数 单节点 > 1000
haproxy_server_status 后端服务器状态 (1=UP, 0=DOWN) = 0
haproxy_backend_http_responses_total HTTP 响应码统计 5xx 比率 > 5%
haproxy_server_response_time_average_seconds 平均响应时间 > 1s

十一、负载均衡算法对比

算法 关键字 特点 适用场景
roundrobin balance roundrobin 按权重轮询(默认权重1) 服务器性能相近
static-rr balance static-rr 静态轮询(运行时不可调整权重) 不需要动态调整
leastconn balance leastconn 最少连接数优先 长连接/API 服务
source balance source 源 IP 哈希(同一 IP 始终分配同一后端) 需要会话保持
uri balance uri URI 哈希(同一 URI 分配同一后端) 缓存场景
first balance first 按顺序填满第一台服务器 节能场景
haproxy 复制代码
# 不同后端使用不同算法
backend web_back
    balance roundrobin      # Web 页面:轮询即可

backend api_back
    balance leastconn       # API:最少连接数(避免长请求堆积)

backend cache_back
    balance uri             # 缓存:同一 URI 命中同一缓存

十二、会话保持(Session Affinity)

12.1 为什么需要会话保持?

复制代码
用户登录 → web-01(Session 在 web-01)
    ↓
再次请求 → web-02(Session 不在 web-02)→ 登录丢失!

12.2 方式1:Source IP Hash

haproxy 复制代码
backend web_back
    balance source          # 同一源 IP 始终分配同一后端
    server web-01 192.168.0.171:80 check
    server web-02 192.168.0.167:80 check

12.3 方式2:Cookie 插入

haproxy 复制代码
backend web_back
    balance roundrobin
    cookie SERVERID insert indirect nocache   # 插入 SERVERID Cookie
    server web-01 192.168.0.171:80 check cookie s1
    server web-02 192.168.0.167:80 check cookie s2

Cookie 参数详解

参数 说明
insert 在响应中插入 Cookie
indirect 不将 Cookie 转发给后端(仅 HAProxy 使用)
nocache 添加 Cache-Control: no-cache(防止 CDN 缓存)

十三、生产环境最佳实践

13.1 安全加固清单

项目 推荐配置 说明
运行用户 user haproxy 不以 root 运行
统计页面 stats auth admin:强密码 避免弱密码
指标端点 acl is_internal src 192.168.0.0/16 仅允许内网访问
连接速率 stick-table 限流 防暴力攻击
SSL 终止 bind *:443 ssl crt HTTPS 加密
日志 option httplog + rsyslog 审计追溯

13.2 性能调优

参数 建议值 说明
maxconn 20000~50000 根据内存调整(每连接约 30KB)
nbthread 自动(=CPU 核心数) HAProxy 3.0 自动检测
timeout client 30s~60s 短连接场景 30s,长连接 60s
option http-server-close 启用 服务端关闭连接,释放资源

13.3 限流配置

haproxy 复制代码
# 在 frontend 中配置 IP 限流
frontend http_front
    bind *:80

    # 定义 stick-table:记录每个 IP 的连接速率
    # type ip: 键为 IP 地址
    # size 100k: 最多记录 10 万个 IP
    # expire 30s: 30 秒无活动则清除
    # store http_req_rate(10s): 记录 10 秒内的请求数
    stick-table type ip size 100k expire 30s store http_req_rate(10s)

    # 检查速率:10 秒内超过 100 次请求则拒绝
    http-request track-sc0 src
    http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }

十四、踩坑记录与排错

踩坑1:HAProxy 源码下载包不完整

复制代码
现象:wget 从 haproxy.org 下载的包仅 1.3MB(完整 4.6MB)
报错:tar: Unexpected EOF in archive
原因:海外节点到 haproxy.org 速度极慢,连接被截断
解决:使用华为云镜像 https://mirrors.huaweicloud.com/haproxy/

踩坑2:nbproc 在 HAProxy 3.0 中已弃用

复制代码
现象:配置 nbproc 2 启动报 ALERT
报错:nbproc is not supported any more since HAProxy 2.5
原因:3.0 版本使用 nbthread(多线程)替代 nbproc(多进程)
解决:删除 nbproc 配置,3.0 自动使用 CPU 核心数的线程

踩坑3:http-request return 语法

复制代码
现象:string 参数中包含 \n 换行符导致解析错误
报错:'http-request return' expects either 'if' or 'unless'
原因:shell heredoc 中 \n 被解释为字面字符
解决:不在 string 参数中使用换行符,或使用 lf 关键字

踩坑4:errorfile 目录不存在

复制代码
现象:配置 errorfile 但 /etc/haproxy/errors/ 目录不存在
报错:error opening file '/etc/haproxy/errors/400.http'
解决:删除 errorfile 配置(非必需),或创建目录和错误页面文件

踩坑5:Keepalived vrrp_strict 与云环境冲突

复制代码
现象:启用 vrrp_strict 后 VIP 无法绑定
原因:云环境 VRRP 组播可能被限制
解决:移除 vrrp_strict,或改用 unicast 对等通信

踩坑6:Keepalived auth_pass 超过 8 字符被截断

复制代码
现象:日志提示 "Truncating auth_pass to 8 characters"
原因:VRRP 协议限制认证密码最长 8 字节
解决:使用 8 字符以内的密码

踩坑7:内网 scp 密码认证失败

复制代码
现象:从 haproxy-02 scp 到 haproxy-01 报 Permission denied
原因:两台服务器 root 密码相同但 SSH 未配置密码认证
解决:直接在目标服务器上写配置文件,或配置 SSH 密钥认证

踩坑8:socat 未安装

复制代码
现象:执行 socat 命令报 command not found
解决:apt install -y socat

十五、总结与延伸

15.1 本教程成果

功能 状态 验证方式
HTTP 负载均衡 (roundrobin) Web-01/Web-02 交替响应
健康检查 (httpchk) 停 web-01 → 自动剔除 → 恢复后自动加回
ACL 规则路由 /api → api_back, /static → static_back
统计页面 http://121.36.66.88:1936/haproxy_stats
Prometheus 指标 http://121.36.66.88:8404/metrics
Keepalived 高可用 VIP 192.168.0.200 漂移 < 6 秒
socat 命令行管理 disable/enable server

15.2 资源消耗

复制代码
组件              内存      CPU
HAProxy 3.0      11MB     0.0%
Keepalived        3MB      0.0%
合计              14MB     ← 极轻量!

15.3 延伸方向

方向 说明
SSL 终止 bind *:443 ssl crt /etc/haproxy/certs/ 实现 HTTPS
gRPC 负载均衡 HAProxy 原生支持 gRPC 代理
限流防刷 stick-table 实现 IP 速率限制
K8s Ingress HAProxy Ingress Controller for Kubernetes
日志接入 Loki HAProxy 日志 → Promtail → Loki → Grafana
TCP 模式 mode tcp 负载均衡 MySQL/Redis 等数据库

📝 附录:本教程所有操作基于华为云 ECS 集群 ecs-8d39(4 台 Ubuntu 24.04)真实执行,输出均为实际命令结果。配置文件可直接用于生产环境(需按实际 IP 修改)。

相关推荐
爱吃牛肉的大老虎2 小时前
SpringCloud之负载均衡 Ribbon和LoadBalancer讲解
spring cloud·ribbon·负载均衡
Java识堂10 小时前
多级负载均衡架构
运维·架构·负载均衡
小黑蛋学java14 小时前
Nginx 接口耗时 Prometheus + Grafana 监控实施方案
运维·nginx·负载均衡·grafana·prometheus
難釋懷1 天前
Nginx使用sticky模块完成对Nginx的负载均衡
运维·nginx·负载均衡
盒子69101 天前
图生图大模型对于各种复杂的图片如何做负载均衡呢?
运维·负载均衡
2401_834636991 天前
Linux 负载均衡全实战:Nginx+HAProxy+LVS 从原理到落地
linux·nginx·负载均衡
2401_834636992 天前
Linux集群技术-高可用与负载均衡实战解析
linux·运维·负载均衡
2601_961194022 天前
考研专业课在哪里参加考试|考点|流程|资料已整理
linux·考研·ubuntu·缓存·centos·负载均衡
遇见小修修5 天前
选择诚信上门修电脑服务,应参考哪些判断标准?
服务器·电脑·负载均衡