keepalived+nginx+tomcat实现高可用天猫商城系统部署

设备需求

5台虚拟机 (2台负载均衡+2台tomcat应用+MySQL数据库)

操作流程如下:

一、环境准备

安装一台全新的LINUX机器,或者查询当前有的主机的环境状态

  • 首先查看和配置网卡信息,以便远程连接控制

    1
    id addr 
  • 连接远程控制

  • 检查防火墙情况

    1
    systemctl status firewalld

    防火墙在学习环境下建议完全关闭,实际生产过程中禁止关闭,规则开放特定端口

  • 检查框架部署环境

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # ========== Nginx 检查 ==========
    # 1. 检查Nginx是否安装
    rpm -qa | grep nginx
    # 2. 检查Nginx运行状态
    systemctl status nginx
    # ========== Keepalived 检查 ==========
    # 1. 检查Keepalived是否安装
    rpm -qa | grep keepalived
    # 2. 检查Keepalived运行状态
    systemctl status keepalived
  • 如果上述环境存在,则直接开始分机部署,如果不存在就看下面

从零开始的项目机器部署

  • 安装一台新机器,并完成远程连接

    做下基础环境

    1
    2
    3
    4
    5
    6
    7
    8
    # 关闭防火墙
    systemctl stop firewalld
    systemctl disable firewalld
    setenforce 0
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

    # 安装依赖
    yum install -y wget gcc gcc-c++ make openssl-devel pcre-devel

    本台机器是原始母机,快照拍摄备案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #检查防火墙状态
    systemctl status firewalld

    #检查SELinux
    getenforce
    # 必须是Permissive 或 Disabled

    # 检查 gcc、gcc-c++、make、openssl-devel、pcre-devel 是否安装
    rpm -qa gcc gcc-c++ make openssl-devel pcre-devel
    # 正常会输出每个包的包名和版本号

    上述基础环境配置完成之后再拍摄快照来备份

开始分机

2 台:Keepalived + Nginx(主备负载均衡)

2 台:Tomcat 应用(Web 服务)

2 台:MySQL 数据库(可做主从,这里先单节点简化)

目标:高可用天猫商城系统,任意一台 Nginx 或 Tomcat 挂掉不影响业务。

6台机器都在原始母机中拍摄的快照得到,环境现在一致,后续做区分

IP地址管理

注意:请勿进入每台机器直接页面,统一使用母机远程连接配置即可,速度极快

如果发生远程连接登录不上(可以联通)按下方排查

1
2
# 查看 SSH 配置
cat /etc/ssh/sshd_config | grep -E "PasswordAuthentication|PermitRootLogin|UseDNS"

查看SSL许可问题

  • PasswordAuthentication yes :密码登录已开启

  • #PermitRootLogin yes :允许 root 登录的配置被注释了(默认 CentOS7 是允许的,但注释状态可能导致行为不确定)

  • #UseDNS yes :DNS 反向解析未关闭,这是认证超时的常见原因

解决上述问题:

1
2
3
4
5
6
7
8
9
# 取消注释并设置为 no
sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config
# 关闭DNS反向解析

# 取消注释并确保为 yes
sed -i 's/#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config
# 明确允许root

systemctl restart sshd

然后尝试连接。

节点类型 主机名 固定 IP 角色 备注
Keepalived+Nginx(负载) LB-MASTER 192.168.111.100 主负载 优先级 100
Keepalived+Nginx(负载) LB-BACKUP 192.168.111.110 备负载 优先级 90
虚拟 IP(VIP) - 192.168.111.10 对外访问入口 飘移 IP,绑定主备负载
Tomcat 应用 Tomcat-01 192.168.111.200 应用节点 1 8080 端口提供服务
Tomcat 应用 Tomcat-02 192.168.111.210 应用节点 2 8080 端口提供服务
MySQL 数据库 MySQL-01 192.168.111.230 主库 3306 端口,写入主节点
MySQL 数据库 MySQL-02 192.168.111.240 从库 3306 端口,只读(先单节点)
1
2
# 网卡配置文件路径
vi /etc/sysconfig/network-scripts/ifcfg-ens33 # 网卡名可能是eth0/ens32,用ip addr看实际名

要是嫌麻烦可以到

1
cd /etc/sysconfig/network-scripts

使用编辑器来快速编辑

配置内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static" #静态IP,必须改static(不是dhcp)
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="528cffee-3172-490e-a4e8-73eae6ff5560"
DEVICE="ens33"
ONBOOT="yes" # 开机自启
IPV6_PRIVACY="no"
# 以下是静态IP核心配置
IPADDR="192.168.117.10" # 每个节点改这里(10/11/20/21/23/24)
NETMASK="255.255.255.0"
GATEWAY="192.168.117.2"
DNS1="8.8.8.8"
DNS2="114.114.114.114"

网卡配置生效:(改完后必须要做)

1
2
3
systemctl restart network  # CentOS7

nmcli connection reload && nmcli connection up ens33 # CentOS8/9

这里只考虑centos系统,winServer,NAS另外处理

1
2
3
4
# 查询网络
ip addr
# 确保互通性
ping 目标ip

确保局域网内各个主机存活性后可以开始正式配置。

这里补充个小细节

二、部署 MySQL 数据库(先部署主库 MySQL-01,MySQL-02 暂作为备用)

操作节点:MySQL-01(192.168.111.230)、MySQL-02(192.168.111.240)

自动化安装(快速部署用)

1. 安装 MySQL

细节参考文档,后续会补充链接

1
2
3
4
5
6
7
8
9
10
11
12
13
# 配置 MySQL 源
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
rpm -ivh mysql80-community-release-el7-3.noarch.rpm

# 安装(跳过GPG检查,避免报错)
yum install -y mysql-community-server --nogpgcheck
# 启动并开机自启

systemctl start mysqld
systemctl enable mysqld

# 验证
systemctl is-active mysqld # 输出 active 即正常

2. 初始化 MySQL-01(主库,仅 192.168.111.230 执行)

(1)获取临时密码

1
2
3
4
5
grep 'temporary password' /var/log/mysqld.log
# 输出示例:2026-03-17T08:00:00.000000Z 6 [Note] [MY-010454] [Server] A temporary

password is generated for root@localhost: abc123!@#
# 复制临时密码(abc123!@# 部分)

(2)登录并修改密码

1
mysql -uroot -p  # 输入上面的临时密码

执行 SQL 命令(密码设为 Mysql@123456,可自定义,需符合强密码规则):

1
2
3
4
5
6
7
8
9
10
-- 修改root密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Mysql@123456';
-- 允许远程访问
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'Mysql@123456';
-- 刷新权限
FLUSH PRIVILEGES;
-- 创建商城数据库
CREATE DATABASE tmall DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 退出
exit;

(3)导入商城 SQL 脚本

这一步在Navicat中和服务器建立稳定连接之后直接在外部执行,避免出现错误

3. MySQL-02 配置(备用节点,仅 192.168.111.240 执行)

暂时和主库配置一致,后续可扩展主从同步:

1
2
# 重复步骤 2.1-2.2,密码设为相同的 Mysql@123456
# 无需导入SQL,后续主从同步后自动同步数据

半自动(手动部署)[更详细]

等待补充

三、部署 Tomcat 应用节点

操作节点:Tomcat-01(192.168.111.200)、Tomcat-02(192.168.111.210)

自动化安装(快速部署用)

1. 安装 JDK(两台都执行)

这是基础环境

1
2
3
yum install -y java-1.8.0-openjdk-devel
# 验证
java -version # 输出 1.8.x 即正常

2. 安装 Tomcat(两台都执行)

1
2
3
4
5
6
7
8
9
10
# 下载 Tomcat 9(稳定版)
cd /usr/local
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.85/bin/apache-tomcat-9.0.85.tar.gz

# 解压并重命名
tar zxf apache-tomcat-9.0.85.tar.gz
mv apache-tomcat-9.0.85 tomcat

# 赋予执行权限
chmod +x /usr/local/tomcat/bin/*.sh

3. 部署天猫商城项目(两台都执行)

(1)上传 war 包

将商城 war 包(如 tmall.war)上传到 /usr/local/tomcat/webapps/

1
2
# 示例:从本地上传(或用 scp 命令)
# scp /本地路径/tmall.war root@192.168.111.200:/usr/local/tomcat/webapps/

这样上传可能被拦截,所以可以通过远程连接直接使用XT上传,这样更直接且更快速

(2)修改数据库连接配置

找到项目的数据库配置文件(根据项目框架调整,以下是常见两种):

情况 1:SpringBoot 项目(application.yml)
1
vi /usr/local/tomcat/webapps/tmall/WEB-INF/classes/application.yml

快速修改就进入到对应文件夹使用编辑器来修改

1
cd /usr/local/tomcat/webapps/tmall/WEB-INF/classes

修改内容:

注意修改URL为你自己的数据库服务地址

1
2
3
4
5
6
spring:
datasource:
url: jdbc:mysql://192.168.111.230:3306/tmall?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: Mysql@123456
driver-class-name: com.mysql.cj.jdbc.Driver
情况 2:传统 XML 配置(jdbc.properties)
1
vi /usr/local/tomcat/webapps/tmall/WEB-INF/classes/jdbc.properties

快速修改就进入到对应文件夹使用编辑器来修改

1
cd /usr/local/tomcat/webapps/tmall/WEB-INF/classes

修改内容:**

1
2
3
4
jdbc.url=jdbc:mysql://192.168.111.230:3306/tmall?useSSL=false&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=Mysql@123456
jdbc.driver=com.mysql.cj.jdbc.Driver

4. 启动 Tomcat(两台都执行)[单台行为也没事]

1
2
3
4
5
6
7
8
9
10
11
12
# 启动
/usr/local/tomcat/bin/startup.sh

# 验证启动
tail -f /usr/local/tomcat/logs/catalina.out # 无 ERROR 即正常

# 验证访问
curl http://127.0.0.1:8080/tmall # 能返回页面 HTML 即正常

# 设置开机自启
echo "/usr/local/tomcat/bin/startup.sh" >> /etc/rc.local
chmod +x /etc/rc.local

外部行为:在使用NAT状态下,在外部windows机器上尝试访问对应的地址,测试项目部署

1
http://192.168.111.200/tmall

半自动(手动部署)[更详细]

四、部署 Keepalived+Nginx 负载节点

操作节点:LB-MASTER(192.168.111.100)主机、LB-BACKUP(192.168.111.110)从机

自动化安装(快速部署用)

1. 安装 Nginx(两台都执行)

1
2
3
4
5
6
7
8
yum install -y nginx
# 启动并开机自启
systemctl start nginx
systemctl enable nginx

# 验证
systemctl is-active nginx # 输出 active 即正常
curl http://127.0.0.1 # 能看到 Nginx 默认页面即正常

外部行为:在使用NAT状态下,在外部windows机器上尝试访问对应的地址,测试项目部署

1
http://192.168.111.100

2. 配置 Nginx 负载均衡(两台都执行)

1
2
# 创建商城配置文件(避免修改默认配置)
vi /etc/nginx/conf.d/tmall.conf

写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 定义 Tomcat 集群
upstream tomcat_cluster {
server 192.168.111.200:8080 weight=1; # Tomcat-01
server 192.168.111.210:8080 weight=1; # Tomcat-02
# weight是会话权重,权重越高,访问请求就会分配的越多
ip_hash; # 会话保持(可选,避免用户登录态丢失)
fail_timeout 10s; # 节点故障超时时间
}

# 对外访问配置
server {
listen 80;
server_name 192.168.111.1; # 绑定 VIP

# 商城项目路径
location / {
proxy_pass http://tomcat_cluster;
# 传递真实IP和主机头
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_connect_timeout 5s;
proxy_read_timeout 60s;
}

# 静态资源缓存(可选,优化性能)
location ~* \.(jpg|jpeg|png|css|js)$ {
proxy_pass http://tomcat_cluster;
proxy_cache_valid 200 1d;
expires 7d;
}
}

验证并重启 Nginx

1
2
3
4
5
nginx -t  # 检查配置语法(输出 ok 即正常)
nginx -s reload

# 验证配置
curl http://127.0.0.1/tmall # 能返回商城页面即正常

外部行为:在使用NAT状态下,在外部windows机器上尝试访问对应的地址,测试项目部署

1
http://192.168.111.100/反向代理地址

3. 安装 Keepalived(两台都执行)

1
yum install -y keepalived

4. 配置 Keepalived(主备区分)

(1)LB-MASTER(192.168.111.100,主节点)

1
vi /etc/keepalived/keepalived.conf

快速修改就进入到对应文件夹使用编辑器来修改

1
cd /etc/keepalived/

写入以下内容(注意网卡名 ens33 需和实际一致):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 全局配置
global_defs {
router_id LB_MASTER # 唯一标识,不能重复
script_user root # 脚本执行用户
enable_script_security
}

# 监控 Nginx 存活状态的脚本
vrrp_script check_nginx {
script "/usr/bin/pgrep nginx" # 检查 Nginx 进程
interval 2 # 每2秒检查一次
weight -20 # 检查失败则优先级减20
}

# VRRP 实例(VIP 飘移核心)
vrrp_instance VI_1 {
state MASTER # 主节点
interface ens33 # 网卡名(需和实际一致)
virtual_router_id 51 # 虚拟路由ID(主备必须一致,0-255)
priority 100 # 优先级(主节点高于备节点)
advert_int 1 # 心跳间隔(1秒)

# 认证配置(主备必须一致)
authentication {
auth_type PASS
auth_pass 123456
}

# 虚拟IP(VIP)
virtual_ipaddress {
192.168.111.1/24 dev ens33 # 飘移IP,绑定网卡
}

# 绑定监控脚本
track_script {
check_nginx
}
}

(2)LB-BACKUP(192.168.111.110,备节点)

1
vi /etc/keepalived/keepalived.conf

快速修改就进入到对应文件夹使用编辑器来修改

1
cd /etc/keepalived/

写入以下内容(仅修改 router_idstatepriority,其他和主节点一致):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
global_defs {
router_id LB_BACKUP
script_user root
enable_script_security
}

vrrp_script check_nginx {
script "/usr/bin/pgrep nginx"
interval 2
weight -20
}

vrrp_instance VI_1 {
state BACKUP # 备节点
interface ens33
virtual_router_id 51
priority 90 # 优先级低于主节点
advert_int 1

authentication {
auth_type PASS
auth_pass 123456
}

virtual_ipaddress {
192.168.111.1/24 dev ens33
}

track_script {
check_nginx
}
}

5. 启动 Keepalived(两台都执行)[关闭一台机器用于测试瘫痪状态]

1
2
3
4
5
6
# 启动并开机自启
systemctl start keepalived
systemctl enable keepalived

# 验证
systemctl is-active keepalived # 输出 active 即正常

6. 验证 VIP 绑定(关键)

(1)主节点验证(LB-MASTER)

1
2
ip addr | grep 192.168.111.1  # 能看到 VIP 绑定在 ens33 上即正常
# 示例输出:inet 192.168.111.1/24 scope global ens33

(2)备节点验证(LB-BACKUP)

1
ip addr | grep 192.168.111.1  # 此时备节点无 VIP,正常

半自动(手动部署)[更详细]

五、高可用验证(测试部分)

1. 基础访问验证

客户端(任意能访问该网段的机器)打开浏览器,访问:

1
http://192.168.111.1/tmall

能正常打开商城页面、登录、操作即基础部署成功。

如果发现更改过代理路由的情况下,请清空浏览器缓存再访问,防止无法成功

2. 负载节点故障验证(主节点挂掉,VIP 飘移)

(1)停止主节点 Keepalived/Nginx

物理手段断电也行 ^-^,反正虚拟机炸了不是我的

1
2
3
4
5
6
# 在 LB-MASTER(192.168.111.100)执行
systemctl stop keepalived

# 或停止 Nginx(触发 Keepalived 自动切换)

# systemctl stop nginx

(2)检查备节点 VIP

1
2
# 在 LB-BACKUP(192.168.111.110)执行
ip addr | grep 192.168.111.1 # 此时备节点会绑定 VIP,正常

(3)验证访问

再次访问 http://192.168.111.1/tmall,业务无中断即正常。

(4)恢复主节点

1
2
3
4
5
# 在 LB-MASTER 执行
systemctl start keepalived

# 验证 VIP 飘回主节点
ip addr | grep 192.168.111.1 # 主节点重新绑定 VIP

3. 应用节点故障验证(单 Tomcat 挂掉)

(1)停止 Tomcat-01

1
2
# 在 Tomcat-01(192.168.111.200)执行
/usr/local/tomcat/bin/shutdown.sh

(2)验证访问

访问 http://192.168.111.1/tmall,Nginx 会自动转发到 Tomcat-02,业务无中断即正常。

(3)恢复 Tomcat-01

1
/usr/local/tomcat/bin/startup.sh

4. 数据库节点验证(多台数据库服务器部署验证)[见后]

停止 MySQL-01(主库),将 Tomcat 配置中的数据库 IP 改为 MySQL-02,重启 Tomcat 后访问正常即备用库生效(后续可配置主从同步实现自动切换)。


六、可选优化

1. Tomcat 日志切割(避免日志过大)

1
2
3
# 在 Tomcat 节点执行
yum install -y logrotate
vi /etc/logrotate.d/tomcat

写入:

1
2
3
4
5
6
7
8
/usr/local/tomcat/logs/catalina.out {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}

2. Nginx 日志配置(便于排查问题)

要会看日志===>INFO大神

1
2
# 在负载节点执行
vi /etc/nginx/conf.d/tmall.conf

server 块中添加:

1
2
access_log /var/log/nginx/tmall_access.log main;
error_log /var/log/nginx/tmall_error.log warn;