基于 CentOS7 搭建 5 节点三层高可用 Web 集群(Nginx+Keepalived+Tomcat+MySQL 主从)

📅 2026/7/22 12:37:30 👁️ 阅读次数 📝 编程学习
基于 CentOS7 搭建 5 节点三层高可用 Web 集群(Nginx+Keepalived+Tomcat+MySQL 主从)

本文记录了本人从零规划、搭建一套 5 节点 CentOS7 高可用 Web 业务集群的完整实操全过程,采用经典三层架构:前端通过 Nginx+Keepalived 基于 VRRP 协议实现负载均衡与虚拟 IP 故障自动漂移,消除网关单点故障;中间层部署两台 Tomcat 服务器承载 Web 应用,分担访问压力;底层使用 MySQL 5.7 搭建一主一从二进制日志复制架构,实现数据实时热备份。 整套环境依托 VMware 虚拟机模板批量克隆部署,搭建过程中踩坑并解决了网段不匹配、端口不通、数据库同步异常、权限策略报错等大量运维常见问题,同时完成主节点宕机故障模拟演练,验证集群业务连续性。

1.模板机初始化 + 5 台虚拟机批量克隆与网络规划

用户访问VIP192.168.2.100 → Keepalived自动把流量切到主Nginx,Nginx做负载均衡转发给Tomcat应用,Tomcat读写MySQL主从数据库。

虚拟机名称集群角色分配静态 IP预装软件
centos-masterNginx 主节点192.168.2.10Nginx、Keepalived
centos-backupNginx 备节点192.168.2.11Nginx、Keepalived
centos-appTomcat 应用服务器192.168.2.12JDK1.8、Tomcat8
centos-mysql1MySQL 主库192.168.2.14MySQL5.7
centos-mysql2MySQL 从库192.168.2.15MySQL5.7

统一对外 VIP:192.168.2.100

准备

先对模板机进行初始化:

切换root模式,全程用root操作

关闭防火墙&设置开机不自启

systemctl stop firewild systemctl disable firewalld

关闭SElinux(永久关闭)

安装必备基础依赖包

作用:• net-tools:提供ifconfig查看网卡IP

• wget:下载安装包

• vim:编辑器

• openssl/pcre:后面编译Nginx必备依赖

执行备份原yum源的命令(把系统默认文件做备份,避免后续出现问题无法回滚)

下载阿里云Centos7源文件

若提示wget找不到,可用curl版本

刷新yum缓存(换源必做!)

查看源文件是否替换成功

安装epel扩展源(后面装keepalived,nginx需要用)

设置主机名(模板机临时名字,克隆后每台再单独改)

优化SSH连接(可选)

系统时间同步(集群时间须统一)

注:模板机保持DHCP自动获取即可

以上执行完成后,关机halt

克隆

卡隆方式要选择 完整克隆!!!依次克隆出五台机器并分别命名

以第一台Nginx主节点master为例:

修改主机名

修改网卡配置为静态IP

清空原有的内容,只修改IPADDR对应的地址

BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.2.10 # 每台替换成表格里的对应IP
NETMASK=255.255.255.0
GATEWAY=192.168.2.2
DNS1=8.8.8.8
DNS2=114.114.114.114

重启网卡服务生效

验证本机IP:ifconfig

连通性测试:在任意一台机器ping其他所有ip,能通代表网络环境已经搭建完成!

2.Nginx+Keepalived 主备负载均衡部署与漂移测试

目的:实现负载均衡+故障自动切换VIP,后端转发到Tomcat

——两台机器都安装Nginx+Keepalived(192.168.2.10,192.168.2.11)

yum install -y nginx keepalived # 设置开机自启
systemctl enable nginx keepalived

systemctl start nginx

——编辑配置文件(两台配置一样)

vim /etc/nginx/nginx.conf

删掉全部原有内容,写入如下配置:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
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;

# 后端Tomcat服务器集群
upstream tomcat_pool {
server 192.168.2.12:8080;
}

server {
listen 80;
server_name _;

location / {
proxy_pass http://tomcat_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}

检查配置:

nginx -t
systemctl restart nginx

配置Keepalived虚拟IP漂移

1.主节点master192.168.2.10:

vim /etc/keepalived/keepalived.conf

完整配置:

global_defs {
router_id NGINX_MASTER
}

vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.2.100/24
}
}

2.备节点backup192.168.2.11:

vim /etc/keepalived/keepalived.conf

完整配置:

global_defs {
router_id NGINX_BACKUP
}

vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.2.100/24
}
}

两台启动Keepalived!

systemctl start keepalived

在主节点查看是否生成VIP:

ip addr

此时192.168.2.100在主节点上,在主节点上执行systemctl stop keepalived,然后去backup执行

ip addr,会发现VIP已经自动切换回来,代表双击热备成功!

3.Tomcat 集群部署 + Nginx 反向代理配置

登录192.168.2.12 centos-app,安装JDK8

yum install -y java-1.8.0-openjdk-devel

验证是否安装成功:

java -version
javac -version

下载并解压Tomcat8.5:

# 下载安装包
wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.98/bin/apache-tomcat-8.5.98.tar.gz

# 解压到 /usr/local 目录
tar -zxvf apache-tomcat-8.5.98.tar.gz -C /usr/local/

编写测试页面,验证Nginx转发

vim /usr/local/tomcat8/webapps/ROOT/index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Server Node: 192.168.2.12 Tomcat</h2>
<p>Access VIP: 192.168.2.100</p>
</body>
</html>

EOF

启动Tomcat

/usr/local/tomcat8/bin/startup.sh

避坑:

为避免系统里不存在这个文件夹路径等,可先查找本机真正的网络根目录

执行find / -name webapps,正常会输出类似:/usr/share/tomcat/webapps 这才是真实路径

然后再用正确路径创建测试页面:

cat > /usr/share/tomcat/webapps/ROOT/index.jsp <<EOF

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Server Node: 192.168.2.12 Tomcat</h2>
<p>Access VIP: 192.168.2.100</p>
</body>
</html>

验证是否创建成功:ls /usr/share/tomcat/webapps/ROOT/ (出现index.jsp即为成功)

放行端口并重启服务:

firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload

浏览器验证:

避坑:

1. 只去连VIP 192.168.2.100,主备节点没启动Keepalived,VIP不存在,必然失败;

2. 桥接没绑定正确物理网卡,虚拟机拿到别的网段IP,局域网不通;

3. 重启后防火墙自动开启,之前临时关闭的设置失效;

高可用故障漂移测试:

1. 关闭当前承载VIP的主Nginx主机

2. 持续刷新网页,只会短暂卡顿一下,页面立刻恢复访问

3. 查看备用机,VIP已经自动漂移过来,实现故障自动切换

4.MySQL 一主一从搭建

主机:centos-mysql1 192.168.2.14(主库 Master)
从机:centos-mysql2 192.168.2.15(从库 Slave)

两台机器执行前置操作:

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0

两台机器安装MySQL5.7:

安装yum源

rpm -ivh https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm

安装服务

yum install -y mysql-community-server
systemctl start mysqld
systemctl enable mysqld

获取初始临时密码

grep 'temporary password' /var/log/mysqld.log

登录并修改密码

mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@123456';
exit;

配置Master主库(192.168.2.14)

编辑配置文件:

vi /etc/my.cnf

写入:

[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

保存退出,重启MySQL:systemctl restart mysqld

登录MySQL,创建账号:mysql -uroot -pRoot@123456

执行:

CREATE USER 'repl'@'%' IDENTIFIED BY 'Repl@123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
-- 锁定库,防止配置期间数据变动
FLUSH TABLES WITH READ LOCK;

查看主库状态,记录File和Position: SHOW MASTER STATUS;

配置Slave主库(192.168.2.15)

编辑配置文件:

vi /etc/my.cnf

写入:

[mysqld]
server-id=2
log-bin=mysql-bin
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

保存退出,重启MySQL:systemctl restart mysqld

登录MySQL,绑定主库:mysql -uroot -pRoot@123456

把下面对应参数换成刚才SHOW MASTER STATUS查询出来的值:

STOP SLAVE;
CHANGE MASTER TO
MASTER_HOST='192.168.2.14',
MASTER_USER='repl',
MASTER_PASSWORD='Repl@123456',
MASTER_LOG_FILE='mysql-bin.000002',#填查到的file名称
MASTER_LOG_POS=747;#填查到的Position数字

启动同步:

START SLAVE;

检查同步状态:

SHOW SLAVE STATUS\G

必须同时满足两个Yes才算成功:

• Slave_IO_Running: Yes

• Slave_SQL_Running: Yes

验证同步效果:

切回主库MySQL窗口,解锁表:

UNLOCK TABLES;

主库新建库,插入测试数据:

CREATE DATABASE test_db;
USE test_db;
CREATE TABLE t(id INT);
INSERT INTO t VALUES(100);

若能从从库查询到这条数据,代表主从搭建完成!

项目总结与后续规划

本次搭建的三层高可用集群,是传统企业机房非常经典的部署方案,完美结合了 TCP/IP 网络原理、VRRP 冗余协议、Linux 系统运维、Web 服务与数据库冗余设计等理论知识。通过亲手完成环境规划、配置部署、错误排查、故障验证,彻底理解了单点故障带来的业务风险,以及负载均衡、主备切换、数据备份的设计意义。

访问链路:
浏览器 → 192.168.2.100(Nginx虚拟VIP)→ 两台Nginx负载均衡 → Tomcat应用节点 → MySQL主库写入、从库同步备份。

现阶段整套集群已经可以稳定运行,为了进一步提升项目深度,后续计划分步完成升级:

  1. 编写 Shell 批量运维脚本,替代重复手动命令,提升部署效率;
  2. 接入 Prometheus+Grafana 监控体系,实现服务器、服务、数据库状态实时监测与异常告警;
  3. 完成 MySQL 读写分离改造,搭配 Redis 缓存优化数据库访问压力;
  4. 使用 Docker 完成服务容器化部署,进一步可向 K8s 编排方向延伸;
  5. 将整套架构迁移至公有云服务器,适配线上生产环境部署逻辑。

本文仅作为个人原创项目实训笔记,可供参考学习,禁止商用二次转载。