Keepalived实战:基于Keepalived+nginx+tomcat+dns搭建双主热备高可用架构设计与实现

**引言:**在互联网业务高速发展的当下,系统可用性已成为衡量业务稳定性的核心指标,尤其是Web服务作为业务入口,其持续运行能力直接决定用户体验与业务收益。传统单节点Web架构易因硬件故障、软件异常、服务崩溃等问题导致业务中断,无法满足企业级应用对高可用性、高可靠性的需求。因此,构建具备故障自动切换、负载均衡能力的高可用架构,成为企业IT基础设施建设的关键环节。

本实验基于KeepalivedNginxTomcatNginx模拟DNS轮询技术,搭建双主热备高可用架构,旨在解决单主热备架构中资源利用率低、单点故障风险高的问题。其中,Tomcat作为后端Web服务容器提供应用支撑,Nginx兼具反向代理与负载均衡功能,实现后端服务的流量分发;Keepalived通过VRRP实现双节点间的主备切换与VIP漂移,保障前端接入的连续性;同时采用Nginx模拟DNS轮询,进一步优化流量分发策略,提升架构整体的并发处理能力与容错性。

1.节点规划
角色 主机名 软件 IP地址
用户 client 192.168.110.90
keepalived vip 192.168.110.100
master master keepalived, nginx 192.168.140
backup backup keepalived, nginx 192.168.141
web tomcat1 tomcat 192.168.110.143
web tomcat2 tomcat 192.168.110.144
DNS轮询 dns nginx 192.168.110.145

实验环境准备:克隆5台服务器,此次实验搭建在安全稳定环境下,首先对每台服务器进行selinux,防火墙的关闭确保操作权限最大化·。

#关闭防selinux
[root@tomcat1 ~]# setenforce 0
[root@tomcat1 ~]# sed -i "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config
#关闭防火墙
[root@tomcat1 ~]# systemctl disable --now firewalld.service 
Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service".
Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service".
2.环境搭建
2.1搭建tomcat1运行环境

首先在tomcat1中安装所需的软件JDK安装包;然后进行解压、验证JDK配置;

#安装和解压,更改配置
[root@tomcat1 ~]# wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz
[root@tomcat1 ~]# tar -zxf jdk-21_linux-x64_bin.tar.gz -C /usr/local
[root@tomcat1 ~]# cd /usr/local/jdk-21.0.10/
[root@tomcat1 jdk-21.0.10]# pwd
/usr/local/jdk-21.0.10
[root@tomcat1 jdk-21.0.10]# vim /etc/profile
[root@tomcat1 jdk-21.0.10]# cat /etc/profile

.....
export JAVA_HOME=/usr/local/jdk-21.0.10
export PATH=$PATH:$JAVA_HOME/bin
#验证配置
[root@tomcat1 jdk-21.0.9]# source /etc/profile
[root@tomcat1 jdk-21.0.9]# java --version
java 21.0.10 2026-1-20 LTS
Java(TM) SE Runtime Environment (build 21.0.10+8-LTS-217)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.9+7-LTS-217, mixed mode, sharing)

然后在tomcat中安装tomcat软件包,并进行解压;

#下载tomcat软件包,解压
[root@tomcat1 jdk-21.0.10]# cd
[root@tomcat1 ~]# wget https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.15/bin/apache-tomcat-11.0.15.tar.gz
[root@tomcat1 ~]# tar -zxf apache-tomcat-11.0.15.tar.gz -C /usr/local
[root@tomcat1 ~]# cd /usr/local/apache-tomcat-11.0.15/
[root@tomcat1 apache-tomcat-11.0.15]# pwd
/usr/local/apache-tomcat-11.0.15

配置tomcat软件,无误后·生效配置,并修改欢迎页;

[root@tomcat1 apache-tomcat-11.0.15]# vim /etc/profile
....
export CATALINA_HOME=/usr/local/apache-tomcat-11.0.15
export PATH=$PATH:$CATALINA_HOME/bin
[root@tomcat1 apache-tomcat-11.0.15]# source /etc/profile
[root@tomcat1 apache-tomcat-11.0.15]# echo "$(hostname) $(hostname -I)" > /usr/local/apache-tomcat-11.0.15/webapps/ROOT/index.jsp

测试环境,启动tomcat,然后访问连接测试。

[root@tomcat1 apache-tomcat-11.0.15]# startup.sh 
Using CATALINA_BASE:   /usr/local/apache-tomcat-11.0.15
Using CATALINA_HOME:   /usr/local/apache-tomcat-11.0.15
Using CATALINA_TMPDIR: /usr/local/apache-tomcat-11.0.15/temp
Using JRE_HOME:        /usr/local/jdk-21.0.9
Using CLASSPATH:       /usr/local/apache-tomcat-11.0.15/bin/bootstrap.jar:/usr/local/apache-tomcat-11.0.15/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@tomcat1 apache-tomcat-11.0.15]# curl localhost:8080
tomcat1 192.168.72.41
2.2搭建tomcat2运行环境

与搭建tomcat1环境一样,但这里使用scp文件传输给tomcat2主机,更加便利;

#复制jdk和tomcat安装目录
[root@tomcat1 ~]# scp -r /usr/local/jdk-21.0.10/ /usr/local/apache-tomcat-11.0.15/ 192.168.110.144:/usr/local/
#复制配置文件
[root@tomcat1 ~]# scp /etc/profile 192.168.110.144:/etc/
root@192.168.110.144's password: 
profile                                                                                            100% 2064     2.4MB/s   00:00    

在tomcat2中验证文件是否完整接收;

[root@tomcat2 ~]# tail -4 /etc/profile
export JAVA_HOME=/usr/local/jdk-21.0.10
export PATH=$PATH:$JAVA_HOME/bin
export CATALINA_HOME=/usr/local/apache-tomcat-11.0.15
export PATH=$PATH:$CATALINA_HOME/bin

生效配置,并启动tomcat;

[root@tomcat2 ~]# source /etc/profile
[root@tomcat2 ~]# startup.sh 
Using CATALINA_BASE:   /usr/local/apache-tomcat-11.0.15
Using CATALINA_HOME:   /usr/local/apache-tomcat-11.0.15
Using CATALINA_TMPDIR: /usr/local/apache-tomcat-11.0.15/temp
Using JRE_HOME:        /usr/local/jdk-21.0.9
Using CLASSPATH:       /usr/local/apache-tomcat-11.0.15/bin/bootstrap.jar:/usr/local/apache-tomcat-11.0.15/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.

修改欢迎页面,进行访问测试。

[root@tomcat2 ~]# echo "$(hostname) $(hostname -I)" > /usr/local/apache-tomcat-11.0.15/webapps/ROOT/index.jsp
[root@tomcat2 ~]# curl localhost:8080
tomcat2 192.168.110.144
2.3搭建master运行环境

首先是安装环境所需的nginx服务,并进行配置;

[root@master ~]# dnf install nginx -y
[root@master ~]# vim /etc/nginx/conf.d/tomcat.conf
[root@master ~]# cat /etc/nginx/conf.d/tomcat.conf
upstream web {
        server 192.168.110.143:8080;
        server 192.168.110.144:8080;
}       
server {
        listen          80;
        server_name     192.168.110.100;
        location / {
                proxy_pass      http://web;
        }
}
#启动nginx服务
[root@master ~]# systemctl start nginx

安装keepalived软件,并进行配置;配置前先对核心文件进行备份,以免源文件丢失或受损;

[root@master ~]# dnf install keepalived -y
[root@master ~]# cp /etc/keepalived/keepalived.conf{,.bak}
[root@master ~]# ll /etc/keepalived/
total 8
-rw-r--r--. 1 root root 3550 May 15  2025 keepalived.conf
-rw-r--r--. 1 root root 3550 Jan 14 11:14 keepalived.conf.bak
[root@master ~]# vim /etc/keepalived/keepalived.conf

#配置文件修改如下
[root@master ~]# cat /etc/keepalived/keepalived.conf
global_defs {
   router_id LVS_master
}

vrrp_instance VI_1 {
    state MASTER
    interface ens160
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.100
    }
}

vrrp_instance VI_2 {
    state BACKUP
    interface ens160
    virtual_router_id 52
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.101
    }
}

启动keepalived软件,并查看ip信息,成功出现两个VIP;

[root@master ~]# systemctl start keepalived.service
[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 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:02:31:f1 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 192.168.110.140/24 brd 192.168.110.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet 192.168.110.100/32 scope global ens160
       valid_lft forever preferred_lft forever
    inet 192.168.110.101/32 scope global ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe02:31f1/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

访问测试:

[root@master ~]# curl 192.168.110.100
tomcat1 192.168.110.143 
[root@master ~]# curl 192.168.110.100
tomcat2 192.168.110.144 
[root@master ~]# curl 192.168.110.100
tomcat1 192.168.110.143 
[root@master ~]# curl 192.168.110.100
tomcat2 192.168.110.144 
2.4搭建backup运行环境

同master环境搭建一致,先进行安装和配置nginx;

[root@backup ~]# dnf install nginx -y
[root@backup ~]# vim /etc/nginx/conf.d/tomcat.conf
[root@backup ~]# cat /etc/nginx/conf.d/tomcat.conf
upstream web {
        server 192.168.110.143:8080;
        server 192.168.110.144:8080;
}       
server {
        listen          80;
        server_name     192.168.110.101;
        location / {
                proxy_pass      http://web;
        }
}
#启动nginx服务
[root@backup ~]# systemctl start nginx

安装和配置keepalived,同样要备份源配置文件,避免流失和损坏;

[root@backup ~]# dnf install keepalived -y
[root@backup ~]# cp /etc/keepalived/keepalived.conf{,.bak}
[root@backup ~]# ll /etc/keepalived/
total 8
-rw-r--r--. 1 root root 3550 May 15  2025 keepalived.conf
-rw-r--r--. 1 root root 3550 Jan 14 11:14 keepalived.conf.bak
[root@master ~]# vim /etc/keepalived/keepalived.conf

#配置文件修改如下
[root@backup ~]# cat /etc/keepalived/keepalived.conf
global_defs {
   router_id LVS_master
}

vrrp_instance VI_1 {
    state MASTER
    interface ens160
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.100
    }
}

vrrp_instance VI_2 {
    state BACKUP
    interface ens160
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.101
    }
}

启动keepalived,并查看VIP情况;

[root@backup ~]# systemctl start keepalived.service
[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 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:9e:32:aa brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 192.168.110.141/24 brd 192.168.110.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet 192.168.110.101/32 scope global ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe9e:32aa/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

自此,backup节点成功搭建。

2.5搭建dns轮询运行环境

采用nginx来充当dns轮询,进行搭建,首先是安装和配置nginx;

[root@dns ~]# dnf install nginx -y

[root@dns ~]# vim /etc/nginx/conf.d/web.conf

upstream web {
        server 192.168.110.100;
        server 192.168.110.101;
}       
server {
        listen          80;
        server_name     192.168.110.145
        location / {
                proxy_pass      http://web;
        }       
}

然后是启动服务,进行访问测试;

[root@dns ~]# systemctl start nginx
[root@dns ~]# systemctl start nginx
[root@dns ~]# curl 192.168.110.145
tomcat1 192.168.110.143 
[root@dns ~]# curl 192.168.110.145
tomcat1 192.168.110.143 
[root@dns ~]# curl 192.168.110.145
tomcat2 192.168.110.144 
[root@dns ~]# curl 192.168.110.145
tomcat2 192.168.110.144 
[root@dns ~]# curl 192.168.110.145
tomcat1 192.168.110.143 
[root@dns ~]# curl 192.168.110.145
tomcat1 192.168.110.143 
[root@dns ~]# curl 192.168.110.145
tomcat2 192.168.110.144 
2.6健康脚本分析

可以发现,DNS轮询在投入架构后成功实现其功能,但该架构仍然存在不足当,master服务器无法感知nginx进程是否存活或出现异常,当出现nginx故障时,整体架构可能会陷入宕机状态,因此我们将编写一个健康检测脚本判断nginx真实运行情况,并触发keepalived及时切换主备。

2.7搭建高可用架构

首先是编写健康检测脚本;

[root@master ~]# vim /etc/keepalived/check_nginx.sh

#内容如下
#!/bin/bash
count=`ps -C nginx --no-header | wc -l`
if [ $count -eq 0 ]; then
        /usr/bin/systemctl start nginx
        sleep 1
        if [ `ps -C nginx --no-header | wc -l` -eq 0 ]; then
                /usr/bin/systemctl stop keepalived
        fi      
fi 

脚本通过对实时nginx进程的抓取来判断nginx服务状态是否正常。

给脚本赋予可执行权限,同时修改keepalived配置文件;

[root@master ~]# chmod +x /etc/keepalived/check_nginx.sh
[root@master ~]# ll /etc/keepalived/check_nginx.sh
-rwxr-xr-x. 1 root root 267 Jan 26 21:34 /etc/keepalived/check_nginx.sh
[root@master ~]# vim /etc/keepalived/keepalived.conf
#文件内容如下
global_defs {
   router_id LVS_master
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2
    timeout 2
    weight -20
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface ens160
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.100
    }
    track_script {
        chk_nginx
    }
}

vrrp_instance VI_2 {
    state BACKUP
    interface ens160
    virtual_router_id 52
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.101
    }
    track_script {
        chk_nginx
    }
}

重启keepalived,并将脚本复制发送到backup服务器;

[root@master ~]# systemctl restart keepalived.service
[root@master ~]# scp -p /etc/keepalived/check_nginx.sh 192.168.110.141:/etc/keepalived/

修改backup主机的keepalived配置文件,同master修改方式一致,这里不过多赘述;然后重启backup服务器中的keepalived服务,进行配置刷新;

[root@backup ~]# systemctl restart keepalived.service
2.8最终运行测试
[root@backup ~]# systemctl stop nginx
[root@backup ~]# curl 192.168.110.145
tomcat1 192.168.110.143
[root@backup ~]# curl 192.168.110.145
tomcat1 192.168.110.143
[root@backup ~]# curl 192.168.110.145
tomcat2 192.168.110.144
[root@backup ~]# curl 192.168.110.145
tomcat2 192.168.110.144
[root@backup ~]# curl 192.168.110.145
tomcat1 192.168.110.143
3.实验总结:

自此该实验项目成功完成,本次实验构建的高可用架构具备较强的实用性与可扩展性,可直接应用于中小型企业的Web服务部署场景,如企业官网、电商平台、内部管理系统等,有效解决单点故障导致的业务中断问题。通过本实验,深入理解了Keepalived的VRRP协议工作机制、Nginx的反向代理与负载均衡原理,以及多组件协同工作的架构设计思路,为后续复杂高可用架构(如分布式服务架构、微服务架构)的搭建奠定了实践基础。

拓展方向:

在实际生产环境中,可基于本架构进行拓展,如增加后端Tomcat节点数量提升并发能力、引入SSL证书实现HTTPS加密传输、部署Redis缓存减轻后端服务压力等,进一步优化架构的性能、安全性与可扩展性,满足不同业务场景的需求。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐