多节点高可用 LAMP 集群架构(Nginx 负载均衡 + MySQL 主从复制 + Orchestrator 自动切换 + Redis 缓存 + NFS 共享存储)

1.架构图

2.原理

2.1什么是nginx

Nginx是一个高性能的 HTTP 服务器 和 反向代理服务器,同时也支持 IMAP/POP3/SMTP 等协议

作用:

1.WEB服务器(静态资源服务)

提供静态文件(如 HTML、CSS、JavaScript、图片等)

2. 反向代理(Reverse Proxy)

将来自客户端的请求转发给后端的应用服务器,并对外隐藏真实服务器的地址

3.负载均衡(Load Balancing)

将流量分发到多个后端服务器,

算法:轮询(round-robin)、加权轮询、IP 哈希、最少连接等

4.缓存(Caching)

可缓存后端响应内容,减少后端压力,加快响应速度

5.SSL/TLS 终止(HTTPS 支持)

可处理 HTTPS 请求,卸载 SSL 加密/解密任务

5.访问控制与安全

可限制 IP 访问、设置速率限制(防 DDOS)、隐藏版本号等,提升服务器安全性

总结:Nginx 是一个轻量、高性能、高并发的 Web 服务器和反向代理工具,常用于静态资源服务、负载均衡、API 网关、HTTPS 终端等场景

2.2什么是orchestator

Orchestrator 是由 GitHub 开源的一款 MySQL 高可用管理与复制拓扑编排工具,专为自动化处理主从复制、故障检测、主库故障自动切换(Failover) 等场景而设计

核心功能:

1.自动发现复制拓扑

2.主库故障检测(Failure Detection)

3.自动主从切换(Automated Failover)

3.钩子(Hooks)与可扩展性

4.Web UI 可视化

3.基础环境和版本信息

10台虚拟机,1G内存,1CPU,20GB,操作系统:Centos7.3。

mysql8.0.44  (数据库)

orchestator3.2.6 (主从切换工具)

nginx1.28.0(入站口,反向代理)

keeplaived2.3.4(高可用)

httpd2.4.62(WEB服务)

php8.3.8(环境)

phpredis6.0.2(用来连接redis)

redis7.4.0(缓存数据)

nfs(版本比较旧,请大家自行升级)

4.mysql主部署流程

1.把 MySQL 官方提供的“仓库配置文件包”装进系统,具体文件放在yum源下
yum install https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm

2.把 MySQL 2023 年新的公钥下载到本地标准目录,文件名叫 RPM-GPG-KEY-mysql-2023
curl -sS https://repo.mysql.com/RPM-GPG-KEY-mysql-2023      -o /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2023

3.以后遇到用这把钥匙签名的包,我认为它合法
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2023

4.把 repo 文件里原来指向的旧钥匙(2022 或 2021 版)统一改成 2023 版,这样 yum 校验时就能对上号,不再出现 “GPG key 已安装但不适用” 的错误
sed -i 's|RPM-GPG-KEY-mysql.*|RPM-GPG-KEY-mysql-2023"|g'      /etc/yum.repos.d/mysql-community.repo

安装mysql8.0.44
###查找mysql软件包#####
 rpm -qa | grep -i mysql

yum -y install mysql-community-server

###缺少工具###
yum -y install net-tools

以上内容均以从相同

5.修改主库配置文件/etc/my.conf,添加一下内容到mysqld模块下
[mysqld]
server_id=100    #给这台 MySQL 一个全局唯一编号(主从不能重复)
log_bin=/var/lib/mysql/mysql-bin    (打开二进制日志,并放在指定路径,文件名前缀 mysql-bin)
binlog_format=ROW    (日志按“行”记录(更精确、更安全,推荐))
gtid_mode=ON    (启用 GTID(全局事务标识),方便主从切换、避免位点错) 
enforce_gtid_consistency=ON   禁止任何会破坏 GTID 一致性的语句(如 CREATE TABLE … SELECT)
binlog_expire_logs_seconds=604800   # 7天自动清理
sync_binlog=1    每次事务提交都立即把 binlog 刷盘,崩溃时最多丢 1 个事务(最安全)

######加入以上内容,必须重启mysqld,不然配置无效
##列出所有已安装的 systemd 单元(服务),把名字里带 "mysql" 的筛出来
systemctl list-unit-files | grep -i mysql  

5.5,获取数据库的临时密码(数据库8.0会临时给一个数据库密码)
awk '/temporary password/ {print $NF}' /var/log/mysqld.log

6.创建专用复制账号
(1)登录数据库
mysql -uroot -p

进入之后,必须重置密码:
alter user 'root'@'localhost' identified by '123456@Yz';

(2)创建专用账号
CREATE USER 'repl'@'192.168.20.137' IDENTIFIED WITH mysql_native_password BY 'Repl@2025Strong';  创建用户、指定从库ip地址及用户密码 

GRANT REPLICATION SLAVE ON *.* TO 'yz'@'192.168.20.144';  用于建立和维护主从复制关系。

(3)orc_client_user:Orchestrator 的 “拓扑监控用户”,管 MySQL 主从集群的监控和切换
-- 1. 先创建 orc_client_user 用户(允许 134 服务器登录,密码 Orch@123 与配置一致)
CREATE USER IF NOT EXISTS 'orc_client_user'@'192.168.20.134' IDENTIFIED BY 'Orch@123';
2. 再授予监控所需权限(SELECT + PROCESS + REPLICATION CLIENT)
GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO'orc_client_user'@'192.168.20.134';

刷新
FLUSH PRIVILEGES;

#查看File和Position值
#show master status;


##安装keepalived配置文件
1.下载源码包
wget https://www.keepalived.org/software/keepalived-2.3.4.tar.gz
2.# 解压 tar 包到 /usr/local
tar -zxvf keepalived-2.3.4.tar.gz -C /usr/local/
3.重命名为 keepalived(简化路径,后续操作更方便)
mv /usr/local/keepalived-2.3.4 /usr/local/keepalived
4. 使用 configure 脚本指定安装路径、依赖库路径等
./configure \
  --prefix=/usr/local/keepalived \     安装路径
  --sysconfdir=/etc/keepalived \      #配置文件目录
  --with-openssl=/usr \             #openssl安装路径
  --with-popt=/usr \                 #popt安装路径
  --with-libnl3=/usr               #libnl3的安装目录
 
 报错:没有C环境    
 第一种方式,安装gcc*
 
 第二种方式:安装gcc-11.2.0          
(1)安装一次性依赖包
yum groupinstall "Development Tools"
yum install gmp-devel mpfr-devel libmpc-devel
(2)下载源码包
wget https://ftp.gnu.org/gnu/gcc/gcc-11.2.0/gcc-11.2.0.tar.gz
(3)解压安装包,并进入解压目录
tar -xf gcc-11.2.0.tar.gz && cd gcc-11.2.0
(4)新建隔离目录
mkdir build && cd build
(5)配置编译
./configure \--prefix=/usr/local/gcc-11.2.0 \     #指定目录
  --enable-languages=c,c++ \
  --disable-multilib \
  --enable-checking=release
(6)编译和安装
make
make install
(7)把新 GCC 放进环境变量
echo 'export PATH=/usr/local/gcc-11.2.0/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/gcc-11.2.0/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/ .bashrc
验证:
gcc   --version   # 应显示 11.2.0
g++   --version


5.编译与安装
make -j $(nproc)  # 多线程编译($(nproc) 自动获取 CPU 核心数,加速编译)
make install      # 安装到指定目录

6.配置环境变量
echo 'export PATH=/usr/local/keepalived/sbin:$PATH' >> /etc/profile
source /etc/profile  # 生效环境变量
验证:
执行 keepalived -v,若输出版本信息(Keepalived v2.3.4)

7.配置keepalived
keepalived配置文件
# /etc/keepalived/keepalived.conf
# ----------- 全局段 -----------
global_defs {
    router_id 1
    script_user root
    enable_script_security
}

# ----------- VRRP 脚本:探活 MySQL -----------
vrrp_script chk_mysql {
    script "/etc/keepalived/check_mysql.sh"   (如果这个脚本发现到数据库主宕机,优先级减50)
    interval 2
    weight -50              # 脚本失败则本机 priority -30
}

# ----------- VRRP 实例 -----------
vrrp_instance VI_1 {
    state BACKUP            # 两台都写 BACKUP,靠 priority 决定主从
    interface ens33         # 实际网卡名
    virtual_router_id 1     # 同一组 VRRP 必须相同
    priority 150            # 另一台写 90
    advert_int 3
    authentication {
        auth_type PASS
        auth_pass 1111      # 同一组密码必须一致
    }
    virtual_ipaddress {
        192.168.20.100/32 dev ens33 label ens33:1   # 要漂移的 VIP
    }
    track_script {
        chk_mysql           # 引用上面定义的探活脚本
    }
    # 当主库恢复时,不自动抢回 VIP(避免频繁切换,可选)
    notify_down "/etc/keepalived/mysql_down.sh"    
}


8.在/etc/keepalived/目录下创建脚本文件
(1)vi check_mysql_sh加入以下内容      
#!/bin/bash
# 检测 MySQL 是否能正常连接
MYSQL_USER="orc_server_user"
MYSQL_PASS="123456"
MYSQL_PORT="3306"

# 执行 MySQL 连接测试
mysql -u$MYSQL_USER -p$MYSQL_PASS -P$MYSQL_PORT -e "SELECT 1" > /dev/null 2>&1

if [ $? -eq 0 ]; then
    # MySQL 正常,返回 0(Keepalived 认为健康)
    exit 0
else
    # MySQL 异常,返回 1(Keepalived 认为故障)
    exit 1
fi

(2)记录日志
#!/bin/bash
# /etc/keepalived/mysql_down.sh

LOG_FILE="/var/log/keepalived_mysql_down.log"
LOCAL_IP=$(hostname -I | awk '{print $1}')
DATE=$(date "+%Y-%m-%d %H:%M:%S")

# 记录宕机日志
echo "[$DATE] 警告:本地 MySQL 主库(IP: $LOCAL_IP)宕机,VIP 192.168.20.100 即将漂移" >> $LOG_FILE

# 可选:发送邮件/短信告警(示例:发送邮件,需安装 mailx)
# echo "MySQL 主库 $LOCAL_IP 宕机,VIP 已漂移" | mailx -s "【MySQL 主库宕机告警】" admin@example.com

exit 0

(3)赋予脚本文件可执行权限
 chmod +x /etc/keepalived/mysql_down.sh
 chmod +x /etc/keepalived/check_mysql.sh


9.需加入主恢复之后,抢占VIP

5.mysql从(slave)部署流程

1.修改从库配置文件/etc/my.conf,添加一下内容到mysqld模块下
[mysqld]
server_id=101    #从库唯一编号,必须和主库不同
report_host = 192.168.20.131     #所有从库都应设置 report_host
否则 Orchestrator、MHA、Prometheus 等工具都无法正确发现拓扑
relay_log=/var/lib/mysql/relay-bin  #指定中继日志文件名前缀(可自定义路径
gtid_mode=ON    #开启 GTID 复制
enforce_gtid_consistency=ON   #保证语句不会破坏 GTID 一致性
read_only=ON                      # 只读模式,普通用户无法写数据,防止误操作(但 root 和 SUPER 权限仍可写)slave_parallel_type=LOGICAL_CLOCK   #按“逻辑时钟”并行回放事务(GTID 复制推荐
slave_parallel_workers=8           # 核数多可再提高
relay_log_purge=ON     #中继日志应用完后自动删除,节省磁盘

######加入以上内容,必须重启mysqld,不然配置无效
2.获取数据库临时密码
awk '/temporary password/ {print $NF}' /var/log/mysqld.log

进入之后,必须重置密码:
alter user 'root'@'localhost' identified by '123456@Yz';

3.使用专用用户来连接主库
CHANGE MASTER TO
  MASTER_HOST='192.168.1.100',   #主库IP地址
  MASTER_USER='repl',     #专用用户
  MASTER_PASSWORD='Repl@2025Strong',     #密码
  MASTER_AUTO_POSITION=1;     
  
 4.开启复制
 start slave;
 
 5.验证
 SHOW SLAVE STATUS\G;
-- 确保以下两项为 Yes--   
Slave_IO_Running: Yes--   
Slave_SQL_Running: Yes--   
Seconds_Behind_Master: 0   (无延迟)

6.##安装keepalived配置文件
1.下载源码包
wget https://www.keepalived.org/software/keepalived-2.3.4.tar.gz
2.# 解压 tar 包到 /usr/local
tar -zxvf keepalived-2.3.4.tar.gz -C /usr/local/

tar 参数命令和含义
z:表示使用 gzip 解压缩。
→ 因为 .tar.gz 文件是先用 tar 打包,再用 gzip 压缩的,所以需要用 -z 来解压 gzip 层。
-x:表示 extract(解包/解压)。
→ 和 -c(create,创建)相对,-x 是把归档文件中的内容提取出来。
-v:表示 verbose(详细模式)。
→ 解压时会列出被解压的文件名,便于用户查看进度和内容。
-f:表示 file(指定文件名)

3.重命名为 keepalived(简化路径,后续操作更方便)
mv /usr/local/keepalived-2.3.4 /usr/local/keepalived
4. 使用 configure 脚本指定安装路径、依赖库路径等
./configure \
  --prefix=/usr/local/keepalived \     安装路径
  --sysconfdir=/etc/keepalived \      #配置文件目录
  --with-openssl=/usr \             #openssl安装路径
  --with-popt=/usr \                 #popt安装路径
  --with-libnl3=/usr               #libnl3的安装目录
 
 ##如果缺少openssl请安装
 报错内容:
 configure: error: 
  !!! OpenSSL is not properly installed on your system. !!!
  !!! Can not include OpenSSL headers files.            !!!

解决方案:
 yum install -y openssl-devel

 ##报错:没有C环境    
 第一种方式,安装gcc*
 
 第二种方式:安装gcc-11.2.0          
(1)安装一次性依赖包
yum groupinstall "Development Tools"
yum install gmp-devel mpfr-devel libmpc-devel
(2)下载源码包
wget https://ftp.gnu.org/gnu/gcc/gcc-11.2.0/gcc-11.2.0.tar.gz
(3)解压安装包,并进入解压目录
tar -xf gcc-11.2.0.tar.gz && cd gcc-11.2.0
(4)新建隔离目录
mkdir build && cd build
(5)配置编译
./configure \--prefix=/usr/local/gcc-11.2.0 \     #指定目录
  --enable-languages=c,c++ \
  --disable-multilib \
  --enable-checking=release
(6)编译和安装
make
make install
(7)把新 GCC 放进环境变量
echo 'export PATH=/usr/local/gcc-11.2.0/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/gcc-11.2.0/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/ .bashrc
验证:
gcc   --version   # 应显示 11.2.0
g++   --version
(8)将keepalived命令加入systemd管理
vi /etc/systemd/system/keepalived.service 
[Unit]
Description=Keepalived High Availability Daemon
Documentation=man:keepalived(8) man:keepalived.conf(5)
After=network.target network-online.target syslog.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/keepalived.pid
ExecStart=/usr/local/keepalived/sbin/keepalived -D -f /etc/keepalived/keepalived.conf     #指定可执行文件和配置文件目录
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target


5.编译与安装
make -j $(nproc)  # 多线程编译($(nproc) 自动获取 CPU 核心数,加速编译)
make install      # 安装到指定目录

6.配置环境变量
echo 'export PATH=/usr/local/keepalived/sbin:$PATH' >> /etc/profile
source /etc/profile  # 生效环境变量
验证:
执行 keepalived -v,若输出版本信息(Keepalived v2.3.4)

7.配置keepalived
# /etc/keepalived/keepalived.conf
# ----------- 全局段 -----------
global_defs {
    router_id 2
    script_user root
    enable_script_security
}

# ----------- VRRP 脚本:探活 MySQL -----------
vrrp_script chk_mysql {
    script "/etc/keepalived/check_mysql.sh"
    interval 2
    weight -30              # 脚本失败则本机 priority -30
}

# ----------- VRRP 实例 -----------
vrrp_instance VI_1 {
    state BACKUP            # 两台都写 BACKUP,靠 priority 决定主从
    interface ens33         # 实际网卡名
    virtual_router_id 1     # 同一组 VRRP 必须相同
    priority 120            # 另一台写 90
    advert_int 3
    authentication {
        auth_type PASS
        auth_pass 1111      # 同一组密码必须一致
    }
    virtual_ipaddress {
        192.168.20.100/32 dev ens33 label ens33:2   # 要漂移的 VIP
    }
    track_script {
        chk_mysql           # 引用上面定义的探活脚本
    }
    # 允许从库成为主库后抢占 VIP(故障转移后保持 VIP 在新主库)
    preempt_delay 30  # 延迟 30 秒抢占(避免网络抖动
    notify_master "/etc/keepalived/mysql_master.sh"
}

8.在/etc/keepalived/目录下创建脚本文件
(1)vi check_mysql_sh加入以下内容      
#!/bin/bash
# 检测 MySQL 是否能正常连接
MYSQL_USER="orc_server_user"   ##确保这个用户可以在本机正常登录
MYSQL_PASS="123456"
MYSQL_PORT="3306"

# 执行 MySQL 连接测试
mysql -u$MYSQL_USER -p$MYSQL_PASS -P$MYSQL_PORT -e "SELECT 1" > /dev/null 2>&1

if [ $? -eq 0 ]; then
    # MySQL 正常,返回 0(Keepalived 认为健康)
    exit 0
else
    # MySQL 异常,返回 1(Keepalived 认为故障)
    exit 1
fi

(2)记录日志
#!/bin/bash
# /etc/keepalived/mysql_down.sh

LOG_FILE="/var/log/keepalived_mysql_down.log"
LOCAL_IP=$(hostname -I | awk '{print $1}')
DATE=$(date "+%Y-%m-%d %H:%M:%S")

# 记录宕机日志
echo "[$DATE] 警告:本地 MySQL 主库(IP: $LOCAL_IP)宕机,VIP 192.168.20.100 即将漂移" >> $LOG_FILE

# 可选:发送邮件/短信告警(示例:发送邮件,需安装 mailx)
# echo "MySQL 主库 $LOCAL_IP 宕机,VIP 已漂移" | mailx -s "【MySQL 主库宕机告警】" admin@example.com

exit 0

(3)赋予脚本文件可执行权限
 chmod +x /etc/keepalived/mysql_down.sh
 chmod +x /etc/keepalived/check_mysql.sh

6.单机部署orchetrator主从切换

防火墙setenforce必须

部署mysql8.0(用做元数据)
1.把 MySQL 官方提供的“仓库配置文件包”装进系统,具体文件放在yum源下
yum install https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm

2.把 MySQL 2023 年新的公钥下载到本地标准目录,文件名叫 RPM-GPG-KEY-mysql-2023
curl -sS https://repo.mysql.com/RPM-GPG-KEY-mysql-2023      -o /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2023

3.以后遇到用这把钥匙签名的包,我认为它合法
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2023

4.把 repo 文件里原来指向的旧钥匙(2022 或 2021 版)统一改成 2023 版,这样 yum 校验时就能对上号,不再出现 “GPG key 已安装但不适用” 的错误
sed -i 's|RPM-GPG-KEY-mysql.*|RPM-GPG-KEY-mysql-2023"|g'      /etc/yum.repos.d/mysql-community.repo

yum -y install mysql 


5.进入数据库,创建元数据用户,并赋予本机登录权限,Orchestrator 的 “数据管理员”,管自己的运行数据存储
mysql -uroot -p
(1)
(2)授权 192.168.20.% 网段(Orchestrator 节点远程连接主从库)
GRANT ALL PRIVILEGES ON `orchestrator`.* TO 'orc_server_user'@'192.168.20.%' IDENTIFIED BY 'Orch@123';-- 
(3) 授权 localhost 本地连接(元数据库节点本地维护时使用)
GRANT ALL PRIVILEGES ON `orchestrator`.* TO 'orc_server_user'@'localhost' IDENTIFIED BY 'Orch@123';


####如果mysql报错###请确定是否安装过其它版本
解决方法:(全新目录 + 彻底授权)
1.停止所有进程
systemctl stop mysqld.service
ps -ef | grep mysqld | grep -v grep | awk '{print $2}' | xargs kill -9 2>/dev/null

2.新建全新的数据目录(远离默认目录
# 1. 创建新目录(选 /data 分区,通常无挂载限制)mkdir -p /data/mysql8
mkdir -p /data/mysql8-files  # 对应 secure-file-priv 目录# 2. 给新目录授权(彻底放开,确保 mysql 用户完全控制)chown -R mysql:mysql /data/mysql8
chown -R mysql:mysql /data/mysql8-files
chmod -R 770 /data/mysql8  # 测试环境宽松权限,避免权限不足chmod -R 770 /data/mysql8-files

# 3. 确认权限(必须是 mysql:mysql,权限 770)ls -ld /data/mysql8
ls -ld /data/mysql8-files


4.修改 MySQL 配置文件(指向新目录)
vim /etc/my.cnf
[mysqld]port=3307  # 确保端口不冲突(3306 被旧从库占用)datadir=/data/mysql8  # 新数据目录socket=/data/mysql8/mysql.sock  socket 文件log-error=/var/log/mysqld.log  # 日志路径不变pid-file=/var/run/mysqld/mysqld.pid  # PID 文件路径不变user=mysqldefault-storage-engine=InnoDBcharacter-set-server=utf8mb4collation-server=utf8mb4_unicode_cisecure-file-priv=/data/mysql8-files  # 新的安全目录# 禁用符号链接(消除警告,可选)skip-symbolic-links=0

5.直接启动 MySQL 服务,让系统自动初始化(关键!)
systemctl start mysqld.service

6.查看启动日志,观察是否在生成系统表tail -f /var/log/mysqld.log | grep -iE "initialize|create table|mysql.db"
###换了mysql路径之后,临时密码的路径/var/log/mysqld.log不会变,所以需要在登录是加入-S指定目录文件
mysql -uroot -p'.*Npd?lD4suB'  -S /data/mysql8/mysql.sock

在配置文件加入
[mysql]
socket=/data/mysql8/mysql.sock

orchestator安装部署
1.下载安装包
wget https://github.com/openark/orchestrator/releases/download/v3.2.6/orchestrator-3.2.6-linux-amd64.tar.gz
2.解压安装包到/usr/local/    (-C代表指定目录)
tar -zxvf orchestrator-3.2.6-linux-amd64.tar.gz -C /usr/local/
3.进入cd /usr/local/orchetrator/下面,原有的配置文件删除加入以下
{
{
  "Debug": true,
  "EnableSyslog": true,        #启用日志
  "SyslogFacility": "local0", 
  "ListenAddress": ":3000",     #WEB监听端口
  "EnableNodeElection": true,
  "InstancePollSeconds": 3,
  "AuditLogFile": "/var/log/orchestrator/orchestrator.log",   #指定日志的写入路径
  "AssumeNodeIsActive": true,     #设置当前节点为活跃状态
  "NodeAddress": "192.168.20.134",    当前 MySQL节点的通信地址
  "MySQLTopologyUser": "orc_client_user",    # 用于探测 MySQL 拓扑的「专用账号」和密码
  "MySQLTopologyPassword": "Orch@123",   
  "MySQLTopologyCredentialsConfigFile": "",
  "MySQLTopologySSLPrivateKeyFile": "",
  "MySQLTopologySSLCertFile": "",
  "MySQLTopologySSLCAFile": "",
  "MySQLTopologySSLSkipVerify": true,
  "MySQLTopologyUseMutualTLS": false,
  "MySQLOrchestratorHost": "192.168.20.134",    #「Orchestrator 元数据库地址」
  "MySQLOrchestratorPort": 3307,   #端口号
  "MySQLOrchestratorDatabase": "Orchestrator",   #Orchestrator 元数据存储的数据库名
  "MySQLOrchestratorUser": "Orchestrator",   #连接「Orchestrator 元数据库」的 MySQL 账号和密码
  "MySQLOrchestratorPassword": "Orch@123",
  "MySQLOrchestratorCredentialsConfigFile": "",
  "MySQLOrchestratorSSLPrivateKeyFile": "",
  "MySQLOrchestratorSSLCertFile": "",
  "MySQLOrchestratorSSLCAFile": "",
  "MySQLOrchestratorSSLSkipVerify": true,
  "MySQLOrchestratorUseMutualTLS": false,
  "MySQLConnectTimeoutSeconds": 1,
  "DefaultInstancePort": 3306,
  "DiscoverByShowSlaveHosts": true,
  "InstancePollSeconds": 5,
  "ClusterNameToAlias": {
  "192.168.20.131:3306": "MySQL-server"},
  "RejectHostnameResolvePattern": "",
  "AllowTLS": false,
  "DiscoveryIgnoreReplicaHostnameFilters": [
    "a_host_i_want_to_ignore[.]example[.]com",
    ".*[.]ignore_all_hosts_from_this_domain[.]example[.]com",
    "a_host_with_extra_port_i_want_to_ignore[.]example[.]com:3307"
  ],
  "UnseenInstanceForgetHours": 240,
  "SnapshotTopologiesIntervalHours": 0,
  "InstanceBulkOperationsWaitTimeoutSeconds": 10,
  "HostnameResolveMethod": "default",
  "MySQLHostnameResolveMethod": "@@hostname",
  "SkipBinlogServerUnresolveCheck": true,
  "ExpiryHostnameResolvesMinutes": 60,
  "RejectHostnameResolvePattern": "",
  "ReasonableReplicationLagSeconds": 10,
  "ProblemIgnoreHostnameFilters": [],
  "VerifyReplicationFilters": false,
  "ReasonableMaintenanceReplicationLagSeconds": 20,
  "CandidateInstanceExpireMinutes": 60,
  "AuditLogFile": "",
  "AuditToSyslog": false,
  "RemoveTextFromHostnameDisplay": ".mydomain.com:3306",
  "ReadOnly": false,
  "AuthenticationMethod": "",
  "HTTPAuthUser": "",
  "HTTPAuthPassword": "",
  "AuthUserHeader": "",
  "PowerAuthUsers": [
    "*"
  ],
  "ClusterNameToAlias": {
    "127.0.0.1": "test suite"
  },
  "ReplicationLagQuery": "",
  "DetectClusterAliasQuery": "SELECT SUBSTRING_INDEX(@@hostname, '.', 1)",
  "DetectClusterDomainQuery": "",
  "DetectInstanceAliasQuery": "",
  "DetectPromotionRuleQuery": "",
  "DataCenterPattern": "[.]([^.]+)[.][^.]+[.]mydomain[.]com",
  "PhysicalEnvironmentPattern": "[.]([^.]+[.][^.]+)[.]mydomain[.]com",
  "PromotionIgnoreHostnameFilters": [],
  "DetectSemiSyncEnforcedQuery": "",
  "ServeAgentsHttp": false,
  "AgentsServerPort": ":3001",
  "AgentsUseSSL": false,
  "AgentsUseMutualTLS": false,
  "AgentSSLSkipVerify": false,
  "AgentSSLPrivateKeyFile": "",
  "AgentSSLCertFile": "",
  "AgentSSLCAFile": "",
  "AgentSSLValidOUs": [],
  "UseSSL": false,
  "UseMutualTLS": false,
  "SSLSkipVerify": false,
  "SSLPrivateKeyFile": "",
  "SSLCertFile": "",
  "SSLCAFile": "",
  "SSLValidOUs": [],
  "URLPrefix": "",
  "StatusEndpoint": "/api/status",
  "StatusSimpleHealth": true,
  "StatusOUVerify": false,
  "AgentPollMinutes": 60,
  "UnseenAgentForgetHours": 6,
  "StaleSeedFailMinutes": 60,
  "SeedAcceptableBytesDiff": 8192,
  "PseudoGTIDPattern": "",
  "PseudoGTIDPatternIsFixedSubstring": false,
  "PseudoGTIDMonotonicHint": "asc:",
  "DetectPseudoGTIDQuery": "",
  "BinlogEventsChunkSize": 10000,
  "SkipBinlogEventsContaining": [],
  "ReduceReplicationAnalysisCount": true,
  "FailureDetectionPeriodBlockMinutes": 60,
  "FailMasterPromotionOnLagMinutes": 0,
  "RecoveryPeriodBlockSeconds": 180,
  "RecoveryIgnoreHostnameFilters": [],
  "RecoverMasterClusterFilters": [
    "*"
  ],
  "RecoverIntermediateMasterClusterFilters": [
    "*"
  ],
  "OnFailureDetectionProcesses": [
    "echo '>>> Detected {failureType} on {failureCluster}' >> /tmp/recovery.log"
  ],
  "PreGracefulTakeoverProcesses": [
    "echo 'Planned takeover about to take place on {failureCluster}. Master will switch to read_only' >> /tmp/recovery.log"
  ],
  "PreFailoverProcesses": [
    "echo '>>> Will recover from {failureType} on {failureCluster}' >> /tmp/recovery.log"
  ],
  "PostFailoverProcesses": [
    "echo '(for all types) Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Successor: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],
  "PostUnsuccessfulFailoverProcesses": [],
  "PostMasterFailoverProcesses": [     
    "echo '>>> Promoted {successorHost}:{successorPort} as new master' >> /tmp/recovery.log",    #故障转移日志记录
    "/usr/local/orchestrator/keepalived-vip.sh {successorHost} {failedHost}"  执行 VIP 漂移脚本  
  ],
  "PostIntermediateMasterFailoverProcesses": [
    "echo 'Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Successor: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],
  "PostGracefulTakeoverProcesses": [
    "echo 'Planned takeover complete' >> /tmp/recovery.log"
  ],
  "CoMasterRecoveryMustPromoteOtherCoMaster": true,
  "DetachLostSlavesAfterMasterFailover": true,
  "ApplyMySQLPromotionAfterMasterFailover": true,
  "PreventCrossDataCenterMasterFailover": false,
  "PreventCrossRegionMasterFailover": false,
  "MasterFailoverDetachReplicaMasterHost": false,
  "MasterFailoverLostInstancesDowntimeMinutes": 0,
  "PostponeReplicaRecoveryOnLagMinutes": 0,
  "OSCIgnoreHostnameFilters": [],
  "GraphiteAddr": "",
  "GraphitePath": "",
  "GraphiteConvertHostnameDotsToUnderscores": true,
  "ConsulAddress": "",
  "ConsulAclToken": "",
  "ConsulKVStoreProvider": "consul",
  "AutoMasterFailover": true,
  "AutoRecoverMaster": true,
  "AutoRecoverIntermediateMaster": true,
  "AutomaticMasterRecoveryMustPromoteOtherInstance": true,
  "PromoteSlavePreferCountReplicas": true,
  "PromoteSlavePreferLagMinutes": 0
}


5.将orchestator服务加入systemd管理
vi /etc/systemd/system/orchestrator.service  加入以下内容:
[Unit]
Description=Orchestrator MySQL Topology Manager
After=network.target mysql.service

[Service]
Type=simple
WorkingDirectory=/usr/local/orchestrator   #orchestator文件目录
User=root               #root用户
Group=root              #root组
ExecStart=/usr/local/orchestrator/orchestrator --config=/usr/local/orchestrator/orchestrator.conf.json http  #启动文件和配置文件目录
Restart=always
RestartSec=5
#可选可不选
StandardOutput=journal+console    #写出日志
StandardError=journal+console

[Install]
WantedBy=multi-user.target

6.重新加载systemd管理,并启动orchestator
systemctl redaom-reload
systemctl restart orchestator

7.将日志文件输出到指定目录,
创建文件:/var/log/orchestrator/orchestrator.log

将syslog下的日志文件写入到自定义目录。
vi /etc/rsyslog.d/30-orchestrator.conf   加入以下内容
# Orchestrator 日志规则(local0 标识匹配)
local0.*        /var/log/orchestrator/orchestrator.log
# 日志格式定义(时间、主机名、应用名)
$template OrchestratorLogFormat, "%timereported% %HOSTNAME% orchestrator: %msg%\n"
local0.*        -/var/log/orchestrator/orchestrator.log;OrchestratorLogFormat
:programname, isequal, "orchestrator" /var/log/orchestrator/orchestrator.log
# 匹配 orchestrator: 前缀的日志(应用自定义格式)
:msg, contains, "orchestrator:" /var/log/orchestrator/orchestrator.log
# 禁止重复转发到系统日志
& ~
# 禁止日志重复转发到系统日志
local0.*        ~

重新启动syslog
systemctl restart syslog
###
查看是否有日志出现:
vi /var/log/orchestrator/orchestrator.log

8.配置钩子脚本/usr/local/orchestrator/
vi   keepalived-vip.sh
#!/bin/bash
# /usr/local/orchestrator/keepalived-vip.sh
# 接收 Orchestrator 传递的参数:$1 = 新主库IP(successorHost),$2 = 旧主库IP(failedHost)

# 配置参数(仅需修改 VIP 和网卡名,与 Keepalived 配置一致)
VIP="192.168.20.100"    #虚拟VIP
INTERFACE="ens33"  # 与 keepalived.conf 中的 interface 一致
LOG_FILE="/var/log/orchestrator-vip-switch.log"   #日志目录

# 校验参数(避免脚本因无参数执行失败)
if [ $# -ne 2 ]; then
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 错误:参数不足!需要 新主库IP 和 旧主库IP" >> $LOG_FILE
    exit 1
fi

# 接收 Orchestrator 传递的变量(动态获取,无需硬编码)
NEW_MASTER="$1"  # 新主库IP(如 192.168.20.137)
OLD_MASTER="$2"  # 旧主库IP(如 192.168.20.131)

# 1. 停止旧主库的 Keepalived(确保旧主库释放 VIP)
echo "$(date +'%Y-%m-%d %H:%M:%S') - 正在停止旧主库 $OLD_MASTER 的 Keepalived..." >> $LOG_FILE
ssh root@$OLD_MASTER "systemctl stop keepalived && systemctl disable keepalived" > /dev/null 2>&1
if [ $? -eq 0 ]; then
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 旧主库 $OLD_MASTER Keepalived 已停止" >> $LOG_FILE
else
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 警告:停止旧主库 $OLD_MASTER Keepalived 失败(可能已宕机)" >> $LOG_FILE
fi

# 2. 启动新主库的 Keepalived(确保新主库绑定 VIP)
echo "$(date +'%Y-%m-%d %H:%M:%S') - 正在启动新主库 $NEW_MASTER 的 Keepalived..." >> $LOG_FILE
ssh root@$NEW_MASTER "systemctl enable keepalived && systemctl start keepalived" > /dev/null 2>&1
if [ $? -eq 0 ]; then
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 新主库 $NEW_MASTER Keepalived 已启动,VIP $VIP 已漂移" >> $LOG_FILE
else
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 错误:启动新主库 $NEW_MASTER Keepalived 失败!" >> $LOG_FILE
    exit 1
fi

# 3. 验证 VIP 是否绑定成功(可选,增强可靠性)
VIP_CHECK=$(ssh root@$NEW_MASTER "ip addr show $INTERFACE | grep $VIP" 2>/dev/null)
if [ -n "$VIP_CHECK" ]; then
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 验证成功:新主库 $NEW_MASTER 已绑定 VIP $VIP" >> $LOG_FILE
else
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 警告:新主库 $NEW_MASTER 未检测到 VIP $VIP,可能绑定失败" >> $LOG_FILE
fi

exit 0


需要做ssh免密,否则钩子脚本停止不到keepalived。
ssh-keygen
ssh-copy-id root@192.168.20.131  

##手动添加集群模式
./orchestrator -c register -i 192.168.20.131:3306  (主)
./orchestrator -c register -i 192.168.20.137:3306   (从)

并验证是否加入集群:
 ./orchestrator -c topology -i 192.168.20.137:3306  
正常状态
025-11-25 02:51:56 DEBUG instanceKey: 192.168.20.131:3306
2025-11-25 02:51:56 DEBUG instanceKey: 192.168.20.137:3306
192.168.20.131:3306   [0s,ok,8.0.44,rw,ROW,>>,GTID]
+ 192.168.20.137:3306 [0s,ok,8.0.44,ro,ROW,>>,GTID]



####查询数据库是读权限还是写
SHOW VARIABLES LIKE 'read_only';
ON 表示 MySQL 实例处于只读模式(即使你有写权限也写不了)
OFF 表示可读写

修改写权限为读
SET GLOBAL read_only = ON;

只要 Orchestrator 成功将从库提升为新主库,就会自动关闭只读模式,让其成为 “可写主库”

在主库上验证 SHOW SLAVE HOSTS


完整的主动联动过程
主库 MySQL 宕机
├─ 1. Keepalived 侧:检测故障
│  - 健康检测脚本(select 1)失败 → 返回 1,Keepalived 判定节点故障;
│  - 触发 mysql_down.sh → 记录日志、发邮件告警;
├─ 2. Orchestrator 侧:主动探测+执行切换
│  - 按周期探测主库 → 连接超时,判定主库故障;
│  - 自动提升从库为新主库(stop slave → reset master);
│  - 触发钩子脚本 keepalived-vip.sh(配置在 Orchestrator 的 PostFailoverProcesses 中);
├─ 3. 脚本联动:Orchestrator 通知 Keepalived 漂移 VIP
│  - keepalived-vip.sh 接收新/旧主库 IP 参数;
│  - 远程停止旧主库 Keepalived → 释放 VIP;
│  - 远程启动新主库 Keepalived → 绑定 VIP;
│  - 验证 VIP 绑定成功;
└─ 4. 业务恢复:
   - VIP 192.168.20.100 已漂移到新主库;
   - 业务通过 VIP 访问 → 连接新主库(可读写),切换完成。

7.配置ngin+keepalived2台同上(用来反向代理WEB网站)

关闭防火墙,setenforce
1.下载源码包
wget https://www.keepalived.org/software/keepalived-2.3.4.tar.gz
2.# 解压 tar 包到 /usr/local
tar -zxvf keepalived-2.3.4.tar.gz -C /usr/local/
3.重命名为 keepalived(简化路径,后续操作更方便)
mv /usr/local/keepalived-2.3.4 /usr/local/keepalived
4. 使用 configure 脚本指定安装路径、依赖库路径等
./configure \
  --prefix=/usr/local/keepalived \     安装路径
  --sysconfdir=/etc/keepalived \      #配置文件目录
  --with-openssl=/usr \             #openssl安装路径
  --with-popt=/usr \                 #popt安装路径
  --with-libnl3=/usr               #libnl3的安装目录
  
 ##如果以上命令输错,重新清理编译生成的文件###
  make clean  # 清理编译生成的 .o 目标文件、可执行文件等
  make distclean  # 额外清理 configure 生成的缓存文件(config.status、Makefile 等)
 
 ##如果缺少openssl请安装
 yum install -y openssl-devel

 ##报错:没有C环境    
 第一种方式,安装gcc*
 
 第二种方式:安装gcc-11.2.0          
(1)安装一次性依赖包
yum groupinstall "Development Tools"
yum install gmp-devel mpfr-devel libmpc-devel
(2)下载源码包
wget https://ftp.gnu.org/gnu/gcc/gcc-11.2.0/gcc-11.2.0.tar.gz
(3)解压安装包,并进入解压目录
tar -xf gcc-11.2.0.tar.gz && cd gcc-11.2.0
(4)新建隔离目录
mkdir build && cd build
(5)配置编译
./configure \--prefix=/usr/local/gcc-11.2.0 \     #指定目录
  --enable-languages=c,c++ \
  --disable-multilib \
  --enable-checking=release
(6)编译和安装
make
make install
(7)把新 GCC 放进环境变量
echo 'export PATH=/usr/local/gcc-11.2.0/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/gcc-11.2.0/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/ .bashrc
验证:
gcc   --version   # 应显示 11.2.0
g++   --version

5.将keepalived命令加入systemd管理
vi /etc/systemd/system/keepalived.service 
[Unit]
Description=Keepalived High Availability Daemon
Documentation=man:keepalived(8) man:keepalived.conf(5)
After=network.target network-online.target syslog.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/keepalived.pid
ExecStart=/usr/local/keepalived/sbin/keepalived -D -f /etc/keepalived/keepalived.conf     #指定可执行文件和配置文件目录
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target


5.编译与安装
make -j $(nproc)  # 多线程编译($(nproc) 自动获取 CPU 核心数,加速编译)
make install      # 安装到指定目录

6.配置环境变量
echo 'export PATH=/usr/local/keepalived/sbin:$PATH' >> /etc/profile
source /etc/profile  # 生效环境变量
验证:
执行 keepalived -v,若输出版本信息(Keepalived v2.3.4)

7.配置keepalived文件:
vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived (Master 节点)
global_defs {
    router_id LVS_MASTER  # 节点唯一标识(主从需不同,如 LVS_MASTER/LVS_BACKUP)
    script_user root       # 执行健康检查脚本的用户
    enable_script_security # 启用脚本安全(2.3.x 推荐开启,避免权限问题)
}

# 健康检查脚本(检测本机核心服务是否正常,如 Nginx/Redis/业务进程)
vrrp_script check_service {
    script "/etc/keepalived/check_service.sh"  # 脚本路径(需手动创建)
    interval 3                                 # 检查间隔(3秒)
    weight -20                                 # 检查失败时,节点权重减20(触发切换)
    fall 2                                     # 连续2次失败视为服务异常
    rise 2                                     # 连续2次成功视为服务恢复
}

# VRRP 实例(核心配置,定义 VIP 和主从关系)
vrrp_instance VI_1 {
    state MASTER                # 节点角色(MASTER/BACKUP)
    interface eth0              # 绑定的网卡(需改为你的实际网卡,如 ens33、eth1)
    virtual_router_id 51        # 虚拟路由ID(主从必须一致,范围 0-255)
    priority 100                # 优先级(MASTER > BACKUP,如 MASTER=100,BACKUP=90)
    advert_int 1                # VRRP 通告间隔(1秒,主从同步心跳)
    
    # 认证配置(主从必须一致,避免非法节点接入)
    authentication {
        auth_type PASS          # 认证方式(PASS 简单密码认证,2.3.x 支持)
        auth_pass 1111          # 认证密码(4位数字,主从需相同)
    }
    
    # 虚拟 IP(VIP,可配置多个,主从切换时自动漂移)
    virtual_ipaddress {
        192.168.1.100/24 dev eth0 label eth0:vip  # VIP + 子网掩码 + 网卡标签
        # 192.168.1.101/24  # 如需多个 VIP,换行添加
    }
    
    # 绑定健康检查脚本(触发故障切换的条件)
    track_script {
        check_service
    }
    
    # (可选)主从切换时执行的钩子脚本(如通知业务、日志记录)
    notify_master "/etc/keepalived/notify.sh MASTER"  # 成为主节点时执行
    notify_backup "/etc/keepalived/notify.sh BACKUP"  # 成为备节点时执行
    notify_fault  "/etc/keepalived/notify.sh FAULT"   # 节点故障时执行
}


8.编译安装nginx1.28.0
1.# 安装基础编译工具、依赖库
yum install -y gcc gcc-c++ make zlib zlib-devel pcre pcre-devel openssl openssl-devel
#(可选)若需支持 IPv6、HTTP/2 等高级功能,补充安装
yum install -y libxslt-devel gd-devel geoip-devel

2.安装源码包
wget https://nginx.org/download/nginx-1.28.0.tar.gz
3.# 验证压缩包完整性(可选,防止下载损坏)# 先获取官方 MD5 校验值:
md5sum nginx-1.28.0.tar.gz
# 对比输出结果与官方 MD5,一致则正常# 解压源码包tar -zxvf nginx-1.28.0.tar.gz
4.# 进入解压后的源码目录
cd nginx-1.28.0
5.配置编译参数
./configure \--prefix=/usr/local/nginx \    # 安装目录(核心,后续所有文件都在这)
--conf-path=/etc/nginx/nginx.conf      ##指定配置文件目录
--user=nginx \                       #运行用户
--group=nginx \                      # 运行组
--with-http_ssl_module \             # 启用 SSL 模块(支持 HTTPS)
--with-http_v2_module \              # 启用 HTTP/2 模块(提升访问速度)
--with-http_realip_module \          # 启用真实 IP 模块(后端服务获取客户端真实 IP)
--with-http_stub_status_module \     # 启用状态监控模块(查看 Nginx 运行状态)
--with-http_gzip_static_module \     # 启用 Gzip 静态压缩模块(优化静态资源传输)
--with-pcre \                        # 启用 PCRE 正则支持(URL 重写必备)
--with-stream \                      # 启用 Stream 模块(支持 TCP/UDP 代理,如数据库代理)
--without-http_autoindex_module \     # 禁用自动索引模块(避免目录遍历风险)
--without-http_ssi_module \          # 禁用 SSI 模块(非必需,减少资源占用)
--with-cc-opt="-O2 -fPIE -fstack-protector-strong" \  # 编译器优化(提升性能+安全)
--with-ld-opt="-Wl,-z,relro,-z,now" 

6.编译和安装
make -j1 
make install

7.将nginx加入systemd管理
vi /etc/systemd/system/nginx.service 
[Unit]
Description=Nginx HTTP Server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
加载systemd管理,并启动nginx
systemctl daemon-reload
systemctl restart nginx
###如果报错请看日志#####
journalctl -u nginx -f --no-pager
##报错内容
nginx: [emerg] unknown log format "main" in /etc/nginx/nginx.conf:25
我遇到的:25行引用了main格式,但配置中没有定义这个日志格式
解决:在nginx配置文件中是有的,只是备注释掉了,打开注释即可
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
重新启动nginx
 systemctl restart nginx          
8.随后修改日志文件的目录,将nginx的日志写入到/var/log/nginx/
创建目录:
touch error.log     #「异常错误信息」
touch access.log    # 记录「正常访问行为」

###nginx正常启动,但是日志文件报错
11月 25 21:44:19 192.168.20.128 systemd[1]: Can't open PID file /usr/local/nginx/logs/nginx.pid (yet?) after start: No such file or directory
解决;在systemd管理里面加入
ExecStartPost=/bin/sleep 1  # 启动后延迟 1 秒,给 Nginx 生成 PID 文件的时间
 加载systemd、关闭nginx所有进程并重启nginx解决
 systemctl daemon-reload
 systemctl stop nginx && pkill -9 nginx
 systemctl restart nginx
 
 
 
 ####nginx配置方向代理#####
 1.只留全局配置,其余全部删除
 vi /etc/nginx/nginx.conf
 user root;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /usr/local/nginx/logs/nginx.pid;
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    include /etc/nginx/proxy.conf;
    default_type application/octet-stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;
    sendfile on;
    keepalive_timeout 65;

}

2.创建代理文件(这个文件只做代理),进入nginx目录
 cd /etc/nginx/
 创建文件
 touch proxy.conf
 3.加入以下配置文件
# upstream backend {
    server 192.168.20.135:80;
    server 192.168.20.132:80;
}

#虚拟主机配置(反向代理核心)
server {
    listen 80;
    server_name 192.168.20.200;  # 你的 Nginx 服务器VIP

    location / {
        proxy_pass http://backend;  # 反向代理转发
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect default;
    }
}








8.部署WEB网站,两台配置同上

1.安装依赖包
yum install -y gcc gcc-c++ make pcre-devel openssl-devel expat-devel  
# 安装 APR 核心库 + 开发包(必需)
yum install -y apr apr-devel apr-util apr-util-devel
2.下载源码包
wget https://dlcdn.apache.org/httpd/httpd-2.4.65.tar.gz
3.解压并接入解压目录
tar -zxvf httpd-2.4.62.tar.gz && cd httpd-2.4.62
4.配置编译参数
./configure \--prefix=/usr/local/httpd \
  --enable-so \
  --enable-ssl \
  --enable-proxy \
  --enable-proxy_http \
  --with-mpm=prefork 
5.编译安装
make -j1
make install

6.将httpd的配置文件复制一份到/etc/httpd/httpd.conf
(1)创建目录
mkdir -p /etc/httpd/
(2)复制到指定目录下
cp /usr/local/httpd/conf/httpd.conf /etc/httpd/
(3)创建日志文件以及httpd的家目录
mkdir -p /var/www/html/
mkdir -p /var/log/httpd/access_log
mkdir -p /var/log/httpd/error_log


7.使用grep查找httpd配置文件的家目录以及日志信息并修改指定目录
(1)查找日志文件
grep 'access_log' /etc/httpd/httpd.conf 
grep 'error_log' /etc/httpd/httpd.conf 
(2)默认家目录是/usr/local/httpd/htdocs/
grep '/var/www/html/' /etc/httpd/httpd.conf   #已修改
DocumentRoot "/var/www/html/"
<Directory "/var/www/html/">


8.创建系统服务管理
[Unit]
Description=Apache HTTP Server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/httpd/bin/apachectl  start -f /etc/httpd/httpd.conf    #指定目录
ExecReload=/usr/local/httpd/bin/apachectl graceful -f /etc/httpd/httpd.conf
ExecStop=/usr/local/httpd/bin/apachectl stop
PIDFile=/usr/local/httpd/logs/httpd.pid
ExecStartPost=/bin/sleep 1 

[Install]
WantedBy=multi-user.target

#查看日志
journalctl -u httpd -f --no-pager

加载systemd单元并重启httpd服务
systemctl daemob-reload
systemctl restart httpd


部署php php-mysqld组件
1.配置华为源,下载安装Remi源时缺少的依赖包epel-release
华为源:
[base]
name=base
baseurl=https://repo.huaweicloud.com/centos/7/os/x86_64/
enable=1
gpgcheck=0
[extras]
name=extrax
baseurl=https://repo.huaweicloud.com/centos/7/extras/x86_64/
enable=1
gpgcheck=0
[updates]
name=updates
baseurl=https://repo.huaweicloud.com/centos/7/updates/x86_64/
enable=1
gpgcheck=0
[queens]
name=queens
baseurl=https://repo.huaweicloud.com/centos/7/cloud/x86_64/openstack-queens/
enable=1
gpgcheck=0
[virt]
name=virt
baseurl=https://repo.huaweicloud.com/centos/7/virt/x86_64/kvm-common/
enable=1
gpgcheck=0


yum install -y epel-release

2.安装php8.3源
yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm

2.启用Remi 源的 PHP 8.4 仓库
yum-config-manager --enable remi-php83
##如果没有这条命令,下载对应的工具包
yum install -y yum-utils

3.安装 PHP 及 MySQL 扩展(mysqlnd 原生驱动)
安装前先把本地源复制到~下面,因为安装php组件时他会先去寻本地源上有没有这个包
mv /etc/yum.repos.d/bdy.repo
在进行安装##
yum install -y php php-mysqlnd

4.# 验证安装
php -v  # 应显示 PHP 8.3.x  
PHP 8.3.8 (cli) (built: Jun  4 2024 14:53:17) (NTS gcc x86_64)

php -m | grep mysql  # 应显示 mysqlnd、mysqli 等扩展



##客户端(WEB1和WEB2)安装phpredis扩展程序
1.下载phpredis扩展程序
wget https://github.com/phpredis/phpredis/archive/refs/tags/6.0.2.tar.gz
或
wget https://gitee.com/mirrors/phpredis/repository/archive/6.0.2.tar.gz -O phpredis-6.0.2.tar.gz
2.解压源码包并进入目录
tar xzf 6.0.2.tar.gz && cd phpredis-6.0.2/
3.用 phpize 初始化构建环境(关键步骤)
phpize   
#如果失败需要安装环境php-devel,如果继续失败请确认版本是否符合
yum install -y php-devel    (因为我之前已经安装过php8.0版本,源在yum里,需要注意,先把本地源移到其它位置,否则先到本地源里去下载php-devel(版本较低,))
4.配置编译目录及其它
./configure  --with-php-config=/usr/bin/php-config  --enable-redis
5.编译安装
make && make install
6.修改vim /etc/php.ini配置文件,添加redis.so模块,加到最后一行即可
extension=redis.so
7.重启Apache服务,写入phpinfo测试页面,通过浏览器访问,http://IP/aa.php
vi   /var/www/html/aa.php  加入以下内容
<?php
phpinfo();
?>
测试:
查看是否有redis模块。

 
 ####客户端访问discuz论坛,发现httpd网站没有解析php模块,导致客户端不能正常访问discuz论坛网站
 1.找到 PHP 模块文件的路径
 find / -name "libphp*.so"   (记住输出的路径)
 比如:/usr/lib64/httpd/modules/libphp.so 
 2.在 Apache 配置文件中添加 PHP 解析配置
 vi /etc/httpd/conf/httpd.conf   (加到httpd配置文件的最后面)
(1) 加载 PHP 模块(路径替换为你找到的 libphp.so 位置)
LoadModule php_module /usr/lib64/httpd/modules/libphp.so

(2). 配置 .php 文件的解析规则:将 .php 后缀的文件交给 PHP 模块处理
AddHandler application/x-httpd-php .php
3.PHP动态网站的通用配置,缺一不可 —— 少了任何一条,都会导致论坛无法正常显示或功能异常
 # 修正后的 Options 行(二选一)
 DocumentRoot "/var/www/html/"  (找到这个模块)
 <Directory "/var/www/html/">   (需加到里面)
    Options Indexes FollowSymLinks ExecCGI  启用 / 禁用当前目录的核心功能
    # 或 Options +Indexes +FollowSymLinks +ExecCGI
    AllowOverride All  允许当前目录及其子目录使用 .htaccess 文件覆盖当前配置
    Require all granted   允许所有客户端访问当前目录(Apache 2.4+ 版本的权限指令
    DirectoryIndex index.php index.html index.htm  指定用户访问目录时,Apache 优先查找的 “默认首页文件”
</Directory>



整体配置的核心用途
这组配置是 搭建动态网站(如 PHP 网站)的基础配置,典型场景:
允许访问目录、跟随软链接(适配网站目录结构);
允许执行 PHP/CGI 脚本(运行动态程序);
支持 .htaccess 自定义规则(比如 WordPress 的固定链接、伪静态);
优先加载动态首页(index.php),兼容静态首页(index.html)


9.部署redis+keepalived,实现数据缓存加高可用

1.# 安装 GCC 编译器、依赖库
yum install -y gcc gcc-c++ make jemalloc-devel openssl-devel tcl
2.创建redis存放目录,并进入目录
mkdir -p /opt/redis/  && cd /opt/redis/
3.# 下载官方源码包(官网直达,无篡改风险)
wget https://download.redis.io/releases/redis-7.4.0.tar.gz
4.# 解压源码包
tar -zxvf redis-7.4.0.tar.gz
5.# 进入源码目录
cd redis-7.4.0
6.# 编译(指定使用 jemalloc 内存分配器,优化性能)
make -j1
7.# 安装到指定目录(默认 /usr/local/redis,可自定义)
make PREFIX=/usr/local/redis install
8.创建日志目录以及配置文件命令
mkdir -p /var/log/redis/  
mkdir -p /etc/redis/  
将redis.conf配置文件和日志文件复制到这个目录
cp redis.conf /etc/redis/      #配置文件
cp redis.log  /var/log/redis/     #日志文件
9.修改reids配置文件的日志目录及redis密码
logfile "/var/log/redis/redis.log"
requirepass 123456  # 默认被注释,示例密码 foobared
###重要###
grep "daemonize" /etc/redis/redis.conf
是否为yes,如果不是立即修改,因为后续redis启动时会报错说start operation timed out. Terminating.

10.将redis加入到systemd管理
[Unit]
Description=Redis 7.4 Server
After=network.target

[Service]
Type=forking
PIDFile=/var/run/redis_6379.pid
ExecStart=/opt/redis/redis-7.4.0/src/redis-server /etc/redis/redis.conf
ExecStop=/opt/redis/redis-7.4.0/src/redis-cli -a 123456 shutdown
Restart=always
User=root
Group=root
TimeoutStartSec=120
TimeoutStopSec=30 
[Install]
WantedBy=multi-user.target


加载配置文件并启动服务
systemctl daemon-erload
systemctl restart redis

11.日志中两个告警,可解决可不解决
(1)TCP 半连接队列限制
73106:M 26 Nov 2025 20:22:08.725 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

解决: 
1. 临时生效sysctl net.core.somaxconn=1024# 
2. 永久生效echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf
加载配置sysctl -p
(2)内存过量使用未开启
WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
解决:
1. 临时生效(无需重启)
sysctl vm.overcommit_memory=1
2. 永久生效(重启服务器后仍有效)
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
加载配置sysctl -p


遇到的问题:
确认 Redis 的 daemonize 配置是 yes(后台启动)?
Type=forking 必须搭配 Redis 的 daemonize yes(默认是 yes),若不小心改成 daemonize no,Redis 会前台运行,不会 fork 子进程,也不会生成 PID 文件,systemd 会一直等 fork 行为,最终超时。


示例 1:bind 127.0.0.1 → 仅本机访问(默认配置,最安全);
示例 2:bind 192.168.20.138 → 仅内网 192.168.20.x 网段能访问;
示例 3:bind 0.0.0.0 或 bind * → 所有网络可访问(需密码 + 防火墙);
示例 4:bind 127.0.0.1 192.168.20.138 → 允许本机 + 内网访问(推荐内网部署)。

9.配置NFS共享存储目录

1.下载nfs-utils*       
yum install -y nfs-utils* 
systemctl  restart   rpcbind  启用进程
systemctl  restart   nfs  启动nfs
2.关闭防火墙   
systemctl stop firewalld
setenforce 0
3.创建共享目录
mkdir -p /luntan/
4.进入共享目录
cd /luntan    
5.使用git下载新版论坛包
git clone https://gitee.com/Discuz/DiscuzX.git
6.将移动upload/的全部东西到当前目录下面
 mv upload/* .  (根据实际情况目录)
7.赋予权限
 chmod -R 757 /luntan config uc_*
8.编写配置文件
vi /etc/exports    加入
/luntan    192.168.10.0/24(rw,sync,no_root_squash,) 
#检测文件内容
exportfs -t
9.启动进程及nfs
systemctl  restart   rpcbind 
systemctl  restart   nfs


客户端WEB1和WEB2安装nfs,并进行挂载目录
1.安装nfs
 yum -y install nfs-utils*
2.挂载目录
mount 192.168.20.130:/luntan /var/www/html/

10.如果访问论坛报错

xml_parser_create()不支持该函数需要 PHP 支持 XML 。请联系服务商,确定开启了此项功能
解决方案:
(1)查询是否只有这三个扩展
php -m | grep -E 'dom|xmlreader'
dom
random
xmlreader
(2)如果没有
1.安装epel源
yum install -y epel-release yum-utils
2.可以从 Remi 仓库下载、安装 PHP 8.3 版本的相关软件包
yum-config-manager --enable remi-php83
3.PHP 8.0 后 php-xml 扩展已拆分,需安装 php-dom 和 php-xmlreader
yum install -y php-dom php-xmlreader

11.总结

本文详细介绍了基于LAMP架构的高可用网站集群部署方案,采用2025年最新版本组件在CentOS7系统上实现。系统架构包含Nginx作为反向代理和负载均衡入口,Apache作为Web服务,MySQL主从集群配合Orchestrator实现自动故障切换,Redis提供缓存服务,NFS实现共享存储。部署过程中重点解决了版本兼容性、服务解析配置、模块加载等技术难点,并通过Keepalived实现各组件的高可用。文章提供了完整的安装配置流程和故障排查方法,最终构建了一个支持主节点故障自动切换、业务不中断的高性能网站集群。测试结果表明,当主节点故障时,系统能够自动完成VIP漂移和主从切换,确保服务持续可用。

blbl视频:https://www.bilibili.com/video/BV12tSnBtEzg/?spm_id_from=333.1387.homepage.video_card.click&vd_source=772e1dce42447e547da0273c613662d6

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢研究新东西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值