基于openEuler系统部署Keepalived+Haproxy集群

1. 规划节点

节点规划,见表1。

表1 节点规划

IP 主机名 节点
192.168.100.3 wordpress1 nginx、php、wordpress
192.168.100.4 wordpress2 nginx、php、wordpress
192.168.100.5 mysql1 mysql
192.168.100.6 mysql2 mysql
192.168.100.7 master keepalived+haproxy
192.168.100.8 backup keepalived+haproxy
192.168.100.100 vip /

2. Keepalived+Haproxy简介

Keepalived+Haproxy 集群是由 Keepalived(高可用组件)Haproxy(负载均衡组件) 协同构成的 高可用负载均衡解决方案,核心是通过 Haproxy 实现后端服务的请求分发与负载分担,同时借助 Keepalived 的 VIP(虚拟 IP)漂移机制与故障检测能力,实时监控集群节点状态,当主节点故障时自动将服务切换至备用节点,从而达成服务无单点故障、请求高效分发、故障快速自愈的核心能力,是 openEuler 系统下微服务、Web 应用、数据库代理等后端服务高可用架构的核心支撑组件。

3. Keepalived+Haproxy架构图

Keepalived+HAProxy 搭建高可用负载均衡

4. Keepalived+Haproxy工作原理

  1. 主节点Haproxy接收客户端请求并分发至后端服务节点,同时记录请求日志与自身服务运行状态;
  2. 主节点Keepalived实时监控本地Haproxy服务状态,将服务健康状态、VIP绑定信息等核心数据传递给自身VRRP发送线程;
  3. 备用节点Keepalived的VRRP接收线程定期向主节点Keepalived的VRRP发送线程请求主节点服务状态与核心配置数据;
  4. 主节点Keepalived的VRRP发送线程将本地Haproxy健康状态、VIP绑定状态等数据同步发送给备用节点的VRRP接收线程;
  5. 备用节点VRRP接收线程确认成功接收主节点状态数据(补充流程连贯性);
  6. 备用节点Keepalived的VRRP接收线程解析主节点发送的状态数据,判断主节点及Haproxy服务是否正常运行;
  7. 备用节点Keepalived将解析后的主节点状态信息、自身配置信息缓存至本地;
  8. 备用节点Keepalived向主节点发送状态同步完成的确认信息;
  9. 主节点Keepalived接收备用节点的确认信息后,完成一次主备状态同步周期;
  10. 当主节点Haproxy或Keepalived服务故障时,备用节点Keepalived读取本地缓存的状态信息,触发VIP漂移机制,启动自身Haproxy服务承接客户端请求,实现集群服务无中断切换。

5. 基础准备

修改master主机名

[root@localhost ~]# hostnamectl set-hostname master
[root@localhost ~]# bash


Welcome to 6.6.0-28.0.0.34.oe2403.x86_64

System information as of time:  Sun Dec  7 03:20:56 PM CST 2025

System load:  0.08
Memory used:  4.1%
Swap used:  0%
Usage On:   3%
IP address:   192.168.100.7
Users online:   1


[root@master ~]# 

修改backup主机名

[root@localhost ~]# hostnamectl set-hostname backup
[root@localhost ~]# bash


Welcome to 6.6.0-28.0.0.34.oe2403.x86_64

System information as of time:  Sun Dec  7 03:21:08 PM CST 2025

System load:  0.00
Memory used:  4.2%
Swap used:  0%
Usage On:   3%
IP address:   192.168.100.8
Users online:   1


[root@backup ~]# 

配置主机映射(两个节点都需要执行)

[root@master ~]# vi /etc/hosts
...
192.168.100.3 wordpress1
192.168.100.4 wordpress2
192.168.100.5 mysql1
192.168.100.6 mysql2
192.168.100.7 master
192.168.100.8 backup

设置防火墙和selinux开机不自启(两个节点都需要执行)

[root@master ~]# systemctl disable firewalld --now && setenforce 0

永久关闭selinux(两个节点都需要执行)

[root@master ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

配置华为云YUM源,openEuler常用repo源链接(两个节点都需要执行)

[root@master ~]# cp -rvf /etc/yum.repos.d/openEuler.repo /tmp/
[root@master ~]# sed -i \
  -e '/^baseurl/ s#http://repo.openeuler.org#https://mirrors.huaweicloud.com/openeuler#g' \
  -e '/^gpgkey/ s#http://repo.openeuler.org#https://mirrors.huaweicloud.com/openeuler#g' \
  /etc/yum.repos.d/openEuler.repo

清理YUM/DNF的所有缓存文件(包括元数据、软件包缓存等)并快速生成YUM缓存(两个节点都需要执行)

[root@master ~]# yum clean all
[root@master ~]# yum makecache

安装工具(两个节点都需要执行)

[root@master ~]# yum install -y vim tar net-tools lrzsz lsof bash-com*
[root@master ~]# source /etc/profile

案例实施

1. 部署 Chrony 时间同步

(1)安装chrony

全部都需要执行

[root@master ~]# yum install -y chrony

启动chrony服务(全部都需要执行)

[root@master ~]# systemctl enable chronyd --now
(2)配备主节点时间同步服务器
[root@master ~]# vim /etc/chrony.conf
# 注释此行 pool pool.ntp.org iburst 添加以下内容
server ntp.aliyun.com iburst
server ntp.tencent.com iburst
allow 192.168.0.0/16
local stratum 10

重启chrony服务

[root@master ~]# systemctl restart chronyd

手动同步时间

[root@master ~]# chronyc makestep
200 OK

查看 NTP 时间源状态

[root@master ~]# chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 203.107.6.88                  2   6   377    55  -4897us[-3796us] +/-   22ms
^+ 106.55.184.199                2   6   377    54  -5868us[-5868us] +/-   50ms
(3)配备其余节点时间同步服务器
[root@backup ~]# vim /etc/chrony.conf 
# 注释此行 pool pool.ntp.org iburst 添加以下内容
server master iburst

重启chrony服务

[root@backup ~]# systemctl restart chronyd

手动同步时间

[root@backup ~]# chronyc makestep
200 OK

查看 NTP 时间源状态

[root@backup ~]# chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* master                        3   6   377    54  +1736us[+2215us] +/-   23ms
(4)配置 亚洲/上海 时区
[root@master ~]# timedatectl set-timezone Asia/Shanghai

验证时区

[root@master ~]# timedatectl 
               Local time: Sun 2025-12-07 18:18:44 CST
           Universal time: Sun 2025-12-07 10:18:44 UTC
                 RTC time: Sun 2025-12-07 10:18:44
                Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

2. 部署 Keepalived 服务

(1)安装keepalived

两个节点都需要执行

[root@master ~]# yum install -y keepalived
(2)配置keeplived文件

配置master节点文件

[root@master ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
# 核心作用:配置Keepalived主节点,实现HAProxy服务健康检测 + VIP(192.168.100.100)高可用漂移
# 适配环境:网卡为ens33,主节点优先级100,备节点建议优先级80

# -------------------------- 全局配置块 --------------------------
global_defs {
    # 全局路由标识:自定义名称,用于日志/监控区分节点,主节点设为LVS_MASTER(备节点可设为LVS_BACKUP)
    router_id LVS_MASTER
    # 指定执行检测脚本的用户:使用root用户(避免脚本权限不足导致检测失败)
    script_user root
    # 启用脚本安全校验:限制脚本只能由script_user指定的用户执行,防止权限漏洞
    enable_script_security
}

# -------------------------- VRRP检测脚本配置:监控HAProxy可用性 --------------------------
# 脚本名称:check_haproxy(需与track_script中关联的名称一致)
vrrp_script check_haproxy {
    # 脚本路径:指定检测HAProxy是否正常运行的自定义脚本(需提前创建并赋予执行权限)
    script "/etc/keepalived/check_haproxy.sh"  
    # 检测间隔:每2秒执行一次脚本,兼顾检测实时性和服务器资源消耗
    interval 2                                 
    # 权重调整:脚本检测失败时,当前节点VRRP优先级降低30(核心!)
    # 主节点初始优先级100 → 失败后70,低于备节点建议的80,触发VIP漂移到备节点
    weight -30                                 
    # 失败阈值:连续2次脚本检测失败,才判定HAProxy故障(避免网络抖动导致误判)
    fall 2                                    
    # 恢复阈值:仅需1次脚本检测成功,就判定HAProxy恢复(快速恢复服务)
    rise 1                                    
}

# -------------------------- VRRP实例配置:核心VIP漂移逻辑 --------------------------
# 实例名称:VI_1(主备节点必须保持一致,否则无法组成同一VRRP集群)
vrrp_instance VI_1 {
    # 节点角色:MASTER(主节点,默认承载VIP;备节点需改为BACKUP)
    state MASTER
    # 绑定的网络接口:你的服务器实际网卡为ens33(非eth0!),VRRP心跳/VIP绑定在此网卡
    interface ens33  
    # 虚拟路由ID:51(主备节点必须一致,范围1-255,同一集群唯一)
    virtual_router_id 51
    # 节点优先级:100(高于备节点的80,确保主节点正常时优先持有VIP)
    priority 100
    # VRRP心跳间隔:每1秒向备节点发送一次心跳包,告知自身存活状态
    advert_int 1
    # 抢占模式:开启(yes),主节点HAProxy恢复后,会主动抢回VIP
    preempt yes
    # 抢占延迟:主节点恢复后,等待10秒再抢回VIP(避免HAProxy刚恢复就抢占,导致服务频繁切换)
    preempt_delay 10  

    # -------------------------- VRRP认证配置:防止非法节点接入 --------------------------
    authentication {
        # 认证类型:PASS(密码认证,另一种AH认证极少使用)
        auth_type PASS
        # 认证密码:1111(主备节点必须完全一致,建议生产环境改为复杂密码)
        auth_pass 1111
    }

    # -------------------------- 虚拟IP(VIP)配置:对外服务的统一入口 --------------------------
    virtual_ipaddress {
        # VIP地址+子网掩码:192.168.100.100/24(主备节点配置一致,故障时自动漂移)
        192.168.100.100/24
    }

    # -------------------------- 关联检测脚本 --------------------------
    track_script {
        # 绑定HAProxy检测脚本:Keepalived会根据脚本结果调整节点优先级,触发VIP漂移
        check_haproxy
    }
}

配置backup节点文件

[root@backup ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
# 核心作用:作为主节点的备用节点,主节点HAProxy故障时自动接管VIP(192.168.100.100)
# 适配环境:网卡ens33,优先级80(低于主节点100),仅在主节点故障时触发VIP漂移

# -------------------------- 全局配置块 --------------------------
global_defs {
    # 全局路由标识:备节点自定义名称,与主节点(LVS_MASTER)区分,便于日志排查
    router_id LVS_BACKUP
    # 指定执行检测脚本的用户:与主节点保持一致,使用root避免权限不足
    script_user root
    # 启用脚本安全校验:与主节点保持一致,限制脚本执行权限
    enable_script_security
}

# -------------------------- VRRP检测脚本配置:与主节点完全一致 --------------------------
# 脚本名称、路径、检测逻辑必须和主节点相同,确保健康检测规则统一
vrrp_script check_haproxy {
    # 检测脚本路径:和主节点使用同一个检测逻辑,确保HAProxy状态判断标准一致
    script "/etc/keepalived/check_haproxy.sh"  
    # 检测间隔:与主节点同步,每2秒检测一次
    interval 2                                 
    # 权重调整:备节点优先级80,失败后减30→50(不影响核心漂移逻辑,仅做冗余)
    weight -30                                 
    # 失败阈值:与主节点同步,连续2次失败判定HAProxy故障
    fall 2                                    
    # 恢复阈值:与主节点同步,1次成功即恢复
    rise 1                                    
}

# -------------------------- VRRP实例配置:核心VIP漂移逻辑(与主节点的差异点标注) --------------------------
vrrp_instance VI_1 {
    # 节点角色:BACKUP(备节点,不主动抢占VIP,仅主节点故障时接管)
    state BACKUP
    # 绑定的网络接口:必须和主节点完全一致(ens33),否则无法接收VRRP心跳
    interface ens33  
    # 虚拟路由ID:必须和主节点完全一致(51),否则不属于同一VRRP集群
    virtual_router_id 51
    # 节点优先级:80(核心!低于主节点的100,确保主节点正常时不抢占VIP)
    priority 80
    # VRRP心跳间隔:与主节点同步,每1秒接收主节点心跳包
    advert_int 1
    # 备节点无需配置抢占(默认preempt no):即使备节点优先级临时高于主节点,也不主动抢VIP
    # 主节点恢复后会自动抢回VIP(主节点配置了preempt yes)
    preempt no

    # -------------------------- VRRP认证配置:与主节点完全一致 --------------------------
    authentication {
        # 认证类型:必须和主节点一致(PASS)
        auth_type PASS
        # 认证密码:必须和主节点一致(1111),否则无法通过认证,无法加入VRRP集群
        auth_pass 1111
    }

    # -------------------------- 虚拟IP(VIP)配置:与主节点完全一致 --------------------------
    virtual_ipaddress {
        # VIP地址+子网掩码:和主节点相同(192.168.100.100/24),故障时接管该IP
        192.168.100.100/24
    }

    # -------------------------- 关联检测脚本:与主节点完全一致 --------------------------
    track_script {
        # 绑定HAProxy检测脚本:监控本机HAProxy状态,确保接管VIP时自身HAProxy可用
        check_haproxy
    }
}

重启keepalived服务

[root@master ~]# systemctl restart keepalived

配置haproxy检测状态脚本

[root@master ~]# vim /etc/keepalived/check_haproxy.sh
#!/bin/bash
# 脚本核心功能:检查HAProxy进程是否运行,若未运行则尝试自动重启;重启失败则停止Keepalived,触发VIP漂移到备用节点
# 日志文件路径:记录检查/重启/故障过程,方便后续排查问题
LOGFILE="/var/log/keepalived-haproxy-state.log"

# 1. 记录当前检查时间到日志(格式如:Thu Dec 18 17:00:00 CST 2025),便于定位问题发生时间
date >> $LOGFILE

# 2. 检查HAProxy进程数量并赋值给变量A
# ps -C haproxy:按进程名筛选haproxy进程
# --no-header:不显示表头(只保留进程行)
# wc -l:统计行数(即进程数量,0表示无haproxy进程,≥1表示有运行)
A=`ps -C haproxy --no-header | wc -l`

# 3. 条件判断:如果HAProxy进程数量为0(未运行)
if [ $A -eq 0 ];then
    # 记录故障日志:标记HAProxy检查失败
    echo "fail: check_haproxy status" >> $LOGFILE
    # 记录操作日志:尝试启动HAProxy服务
    echo "Try to start haproxy service" >> $LOGFILE
    # 执行启动HAProxy的命令(自动恢复尝试)
    systemctl start haproxy  
    # 等待2秒:给HAProxy启动的时间(避免检查过快导致误判)
    sleep 2
    # 再次检查HAProxy进程数量:判断重启是否成功
    # `ps -C haproxy --no-header | wc -l`:重新统计进程数
    # -eq 0:如果仍为0,说明重启失败
    if [ `ps -C haproxy --no-header | wc -l` -eq 0 ];then  
        # 记录故障日志:HAProxy启动失败,将停止Keepalived触发VIP漂移
        echo "Can not start haproxy service, so will stop keepalived service" >> $LOGFILE
        # 强制杀死所有Keepalived进程(停止Keepalived),master节点释放VIP
        killall keepalived
    fi
# 4. 条件判断:如果HAProxy进程数量≥1(运行正常)
else
    # 记录成功日志:标记HAProxy检查正常
    echo "success: check_haproxy status" >> $LOGFILE
fi

添加脚本执行权限

[root@master ~]# chmod +x /etc/keepalived/check_haproxy.sh
(3)设置keepalived开机自启

两个节点都需要执行

[root@master ~]# systemctl enable keepalived --now

查看master节点的漂移VIP

[root@master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:2f:f2:cb brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.7/24 brd 192.168.100.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.100.100/24 scope global secondary ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe2f:f2cb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
(4)测试VIP漂移

在master节点停止keepalived服务

[root@master ~]# systemctl stop keepalived

查看master的vip是否存在

[root@master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:2f:f2:cb brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.7/24 brd 192.168.100.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe2f:f2cb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

在backup节点查看vip是否存在

[root@backup ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:39:cc:be brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.8/24 brd 192.168.100.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.100.100/24 scope global secondary ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe39:ccbe/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

3. 配置 Haproxy 服务

(1)安装haproxy
[root@master ~]# yum install -y haproxy

开机自启动haproxy服务

[root@master ~]# systemctl enable haproxy --now
(2)配置haproxy文件
[root@master ~]# vim /etc/haproxy/haproxy.cfg
# --- GLOBAL ---
# 全局配置块:HAProxy进程级核心配置,整个实例仅生效一次,影响全局性能与安全
global
    # 日志配置:将不同级别日志输出到系统syslog
    # local0(info):记录详细请求日志,便于排查问题;local1(notice):记录重要通知日志
    log /dev/log local0 info
    log /dev/log local1 notice
    
    # 安全隔离:将HAProxy进程限制在/var/lib/haproxy目录(chroot监狱)
    # 作用:即使HAProxy被攻破,攻击者也无法访问其他系统目录,降低安全风险
    chroot /var/lib/haproxy
    
    # PID文件路径:记录HAProxy主进程ID,便于系统管理(如systemctl重启/停止)
    pidfile /run/haproxy.pid
    
    # 全局最大并发连接数:20万(适配高流量WordPress站点,需结合服务器硬件调整)
    maxconn 200000
    
    # 运行HAProxy的用户/用户组:使用系统低权限的haproxy用户,避免root权限风险
    user haproxy
    group haproxy
    
    # 守护进程模式:HAProxy在后台运行(生产环境必配,避免终端关闭后进程退出)
    daemon

    # 性能优化:设置4个工作线程(建议等于服务器CPU核心数,如8核设8)
    # 作用:利用多核CPU并行处理请求,提升WordPress并发处理能力
    nbthread 4
    
    # SSL安全优化:设置SSL默认DH参数长度为2048位(即使暂不用HTTPS也建议保留)
    # 作用:符合安全规范,后续开启HTTPS时无需重新配置
    tune.ssl.default-dh-param 2048

# --- DEFAULTS ---
# 默认配置块:所有frontend/backend/listen会继承此配置,减少重复配置量
defaults
    # 工作模式:HTTP模式(适配WordPress的HTTP/HTTPS请求,区别于TCP模式)
    mode http
    
    # 日志继承:使用global块的日志配置规则
    log global
    
    # 启用HTTP日志:记录完整的HTTP请求信息(如URL、状态码、客户端IP、响应时间)
    option httplog
    
    # 关闭空连接日志:不记录无数据传输的空连接(如端口扫描),减少日志冗余
    option dontlognull
    
    # 重分发:当后端WordPress节点故障时,将请求重新分发到其他健康节点
    # 作用:避免用户请求因单个节点故障直接失败,保证WordPress服务高可用
    option redispatch
    
    # 重试次数:请求失败后重试3次(适配WordPress临时网络波动/数据库慢查询场景)
    retries 3

    # 超时配置(针对WordPress场景优化,平衡性能与用户体验):
    # 1. HTTP请求头读取超时:10秒(避免慢请求占用连接资源)
    timeout http-request 10s
    # 2. 请求队列超时:30秒(请求排队等待后端节点的最长时间)
    timeout queue        30s
    # 3. HAProxy与后端WordPress节点的连接超时:5秒(快速失败,避免阻塞)
    timeout connect      5s
    # 4. 客户端连接超时:60秒(适配WordPress静态资源/大文件下载场景)
    timeout client       60s
    # 5. 后端服务器响应超时:60秒(适配WordPress数据库查询/插件加载耗时场景)
    timeout server       60s
    # 6. HTTP长连接超时:10秒(复用TCP连接,减少握手开销,提升性能)
    timeout http-keep-alive 10s

    # 每个frontend/backend的最大并发连接数:5万(不超过global的maxconn上限)
    maxconn 50000
    
    # 自定义503错误页:后端所有WordPress节点故障时,返回自定义的503页面
    # 需提前创建/etc/haproxy/errors/503.http文件,提升用户体验
    errorfile 503 /etc/haproxy/errors/503.http

# --- FRONTEND ---
# 前端配置块:接收客户端请求的入口,相当于HAProxy的"请求大门"
frontend http_front
    # 绑定端口:监听本机所有IP的80端口(适配Keepalived浮动IP漂移场景)
    # 作用:无论VIP(192.168.100.100)飘到主/备节点,都能接收请求
    bind *:80
    # 工作模式:显式声明HTTP模式(与defaults一致,增强配置可读性)
    mode http

    # 透传真实客户端IP(WordPress核心需求):
    # 1. 启用X-Forwarded-For头,记录客户端真实IP(而非HAProxy的IP)
    option forwardfor
    # 2. 设置X-Forwarded-Proto头为http(WordPress需识别协议类型,避免跳转异常)
    http-request set-header X-Forwarded-Proto http

    # 默认后端:所有未匹配特殊规则的请求,转发到wordpress_backend处理
    default_backend wordpress_backend

# --- BACKEND ---
# 后端配置块:处理请求转发到WordPress节点的核心逻辑
backend wordpress_backend
    # 工作模式:HTTP模式
    mode http
    
    # 负载均衡算法:轮询(roundrobin)
    # 特点:请求平均分配到每个WordPress节点,适配无状态的前台请求
    # 可选算法:source(按客户端IP哈希,固定会话)、leastconn(最少连接数)
    balance roundrobin

    # ---- 健康检查(HAProxy 2.9+ 正确写法,核心!)----
    # 1. 启用HTTP健康检查总开关(必须加,否则后续http-check规则被忽略)
    option httpchk
    # 2. 发送健康检查请求:GET /healthz.html,带HTTP/1.1协议和Host头
    # uri /healthz.html:检查WordPress节点的健康页(需在节点创建该文件)
    # hdr Host localhost:指定Host头,避免WordPress虚拟主机匹配失败
    http-check send meth GET uri /healthz.html ver HTTP/1.1 hdr Host localhost
    # 3. 健康判定规则:期望后端返回200状态码(返回其他码则判定节点故障)
    http-check expect status 200

    # ---- WordPress 会话保持(后台登录必备)----
    # cookie SERVERID:自定义Cookie名称为SERVERID
    # insert:HAProxy自动插入该Cookie到响应中
    # indirect:仅对后端节点的响应设置Cookie,不主动发给客户端
    # nocache:告知浏览器不缓存该Cookie,避免会话错乱
    # 作用:同一客户端的请求固定分发到同一WordPress节点,避免后台登录后跳转到其他节点登出
    cookie SERVERID insert indirect nocache

    # ---- 后端服务器默认参数(必须一行写,HAProxy语法要求)----
    # inter 3s:每3秒检查一次节点健康状态
    # fall 3:连续3次检查失败,判定节点DOWN(剔除出集群)
    # rise 2:连续2次检查成功,判定节点UP(重新加入集群)
    # slowstart 10s:节点恢复后,10秒内逐步恢复流量(避免瞬间高负载压垮节点)
    # maxconn 2000:每个WordPress节点的最大并发连接数
    default-server inter 3s fall 3 rise 2 slowstart 10s maxconn 2000

    # ---- 真实 WordPress 节点配置 ----
    # server 节点名 IP:端口 检查参数 Cookie标识
    # check:启用健康检查(继承default-server的检查规则)
    # cookie wp1/wp2:为节点设置Cookie标识(配合会话保持)
    server wp1 192.168.100.3:80 check cookie wp1
    server wp2 192.168.100.4:80 check cookie wp2

# --- STATS ---
# 监控页配置块:HAProxy自带的状态监控页面,便于实时查看集群状态
listen stats
    # 绑定端口:监听本机所有IP的8404端口(可自定义,如8080)
    bind *:8404
    # 工作模式:HTTP模式(监控页为HTTP页面)
    mode http
    
    # 启用监控页功能(核心开关)
    stats enable
    # 监控页访问路径:http://HAProxyIP:8404/haproxy-stats
    stats uri /haproxy-stats
    # 监控页自动刷新时间:5秒(实时更新节点状态)
    stats refresh 5s
    # 监控页认证:用户名admin,密码admin123(生产环境建议设复杂密码)
    stats auth admin:admin123

在WordPress节点配置健康检查文件

[root@wordpress1 ~]# vim /usr/share/nginx/html/healthz.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>wordpress2 - 服务健康状态</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: "Microsoft YaHei", Arial, sans-serif;
        }
        body {
            background-color: #f0f8f0;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 20px;
        }
        .health-card {
            background-color: #ffffff;
            border-radius: 12px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
            padding: 40px 60px;
            text-align: center;
            max-width: 500px;
            width: 100%;
        }
        .health-icon {
            font-size: 60px;
            color: #28a745;
            margin-bottom: 20px;
        }
        .health-title {
            font-size: 24px;
            color: #333333;
            margin-bottom: 10px;
            font-weight: 600;
        }
        .health-desc {
            font-size: 16px;
            color: #666666;
            margin-bottom: 20px;
        }
        .server-info {
            font-size: 14px;
            color: #999999;
            border-top: 1px solid #eeeeee;
            padding-top: 15px;
            margin-top: 15px;
        }
    </style>
</head>
<body>
    <div class="health-card">
        <div class="health-icon">✓</div>
        <!-- 页面内也显示主机名,更直观 -->
        <h1 class="health-title">wordpress2 - 服务运行正常</h1>
        <p class="health-desc">当前节点健康状态良好,可正常处理请求</p>
        <div class="server-info">
            <p>健康检查时间:<span id="check-time"></span></p>
            <p>节点主机名:wordpress2</p>
        </div>
    </div>

    <script>
        document.getElementById('check-time').textContent = new Date().toLocaleString('zh-CN');
    </script>
</body>
</html>

创建自定义的 503 错误页面文件,用于当 HAProxy 后端所有 WordPress 节点都故障(DOWN)时显示

[root@master ~]# mkdir -p /etc/haproxy/errors/
[root@master ~]# vim /etc/haproxy/errors/503.http
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html; charset=utf-8

<html>
<head><title>服务暂时不可用</title></head>
<body>
<h1>503 Service Unavailable</h1>
<p>服务器正在维护,请稍后重试</p>
</body>
</html>

重启服务

[root@master ~]# systemctl restart haproxy

通过vip测试

[root@master ~]# curl http://192.168.100.100/healthz.html | grep wordpress
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2245  100  2245    0     0   474k      0 --:--:-- --:--:-- --:--:--  548k
    <!-- 自动注入主机名作为标题前缀:wordpress1会被Shell解析为服务器主机名 -->
    <title>wordpress1 - 服务健康状态</title>
        <h1 class="health-title">wordpress1 - 服务运行正常</h1>
            <p>节点主机名:wordpress1</p>
[root@master ~]# curl http://192.168.100.100/healthz.html | grep wordpress
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2245  100  2245    0     0   671k      0 --:--:-- --:--:-- --:--:--  730k
    <!-- 自动注入主机名作为标题前缀:wordpress2会被Shell解析为服务器主机名 -->
    <title>wordpress2 - 服务健康状态</title>
        <h1 class="health-title">wordpress2 - 服务运行正常</h1>
            <p>节点主机名:wordpress2</p>

查看监控面板 http://192.168.100.100:8404/haproxy-stats

image-20251218190135862

posted @ 2026-04-26 03:04  陌殇殇殇  阅读(38)  评论(0)    收藏  举报