基于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架构图

4. Keepalived+Haproxy工作原理
- 主节点Haproxy接收客户端请求并分发至后端服务节点,同时记录请求日志与自身服务运行状态;
- 主节点Keepalived实时监控本地Haproxy服务状态,将服务健康状态、VIP绑定信息等核心数据传递给自身VRRP发送线程;
- 备用节点Keepalived的VRRP接收线程定期向主节点Keepalived的VRRP发送线程请求主节点服务状态与核心配置数据;
- 主节点Keepalived的VRRP发送线程将本地Haproxy健康状态、VIP绑定状态等数据同步发送给备用节点的VRRP接收线程;
- 备用节点VRRP接收线程确认成功接收主节点状态数据(补充流程连贯性);
- 备用节点Keepalived的VRRP接收线程解析主节点发送的状态数据,判断主节点及Haproxy服务是否正常运行;
- 备用节点Keepalived将解析后的主节点状态信息、自身配置信息缓存至本地;
- 备用节点Keepalived向主节点发送状态同步完成的确认信息;
- 主节点Keepalived接收备用节点的确认信息后,完成一次主备状态同步周期;
- 当主节点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


浙公网安备 33010602011771号