1. 高可用Web服务架构设计与实现
在企业级Web服务部署中,确保服务的高可用性是最基本的要求。今天我要分享的是一个经过生产环境验证的经典方案:基于Keepalived+Nginx+Tomcat的高可用Web服务架构。这个架构不仅能实现负载均衡,还能在主节点故障时自动切换,确保服务不间断运行。
这套架构的核心组件分工明确:
- Tomcat:作为应用服务器运行Java Web应用
- Nginx:承担反向代理和负载均衡职责
- Keepalived:实现VIP(虚拟IP)漂移,提供高可用保障
我曾在多个生产环境中部署过这个架构,最大的优势在于它的简单可靠——没有复杂的依赖,各组件职责清晰,故障排查也相对容易。下面我就详细拆解整个部署过程。
2. 环境规划与准备
2.1 节点规划与网络拓扑
一个合理规划的部署环境是成功的基础。根据经验,我建议采用以下节点分配方案:
| IP地址 | 主机名 | 软件 | 节点角色 |
|---|---|---|---|
| 192.168.72.30 | master | keepalived, nginx | 主节点 |
| 192.168.72.32 | backup | keepalived, nginx | 备用节点 |
| 192.168.72.100 | - | - | VIP地址 |
| 192.168.72.41 | web1 | tomcat, jdk | 应用节点1 |
| 192.168.72.42 | web2 | tomcat, jdk | 应用节点2 |
实际部署时需要注意:所有节点应在同一局域网段,且VIP地址不应被其他设备占用。我建议将VIP设置为与物理IP同网段但末尾数字较大的地址(如.100),这样既好记又不容易冲突。
2.2 基础环境清理
在开始安装前,确保master和backup节点上的旧服务已彻底清理:
bash复制# 停止并删除旧服务(两台节点都需要执行)
systemctl stop keepalived nginx
dnf remove -y nginx keepalived
rm -rf /etc/keepalived
这个清理步骤很重要,特别是当节点之前运行过其他版本的软件时。我曾遇到过因为旧配置文件残留导致的服务异常,所以现在养成了彻底清理的习惯。
2.3 Tomcat节点配置
对于Tomcat节点,我们需要完成以下准备工作:
- 设置主机名和静态IP:
bash复制# 在web1节点执行
hostnamectl set-hostname web1 && bash
nmcli c modify ens160 ipv4.method manual \
ipv4.addresses 192.168.72.41/24 \
ipv4.gateway 192.168.72.2 \
ipv4.dns 223.5.5.5 \
connection.autoconnect yes
nmcli c up ens160
# 在web2节点执行相同操作,只需修改IP为192.168.72.42
- 关闭SELinux和防火墙:
bash复制setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=permissive/" /etc/selinux/config
systemctl disable --now firewalld
生产环境中,建议配置精细的防火墙规则而不是完全关闭。但在测试环境或内网部署时,直接关闭可以简化配置过程。
3. Tomcat集群部署
3.1 JDK安装与配置
Tomcat运行依赖Java环境,我们选择最新的JDK 21 LTS版本:
bash复制# 下载并安装JDK
wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz
tar -zxf jdk-21_linux-x64_bin.tar.gz -C /usr/local/
# 配置环境变量
echo 'export JAVA_HOME=/usr/local/jdk-21.0.9
export PATH=$PATH:$JAVA_HOME/bin' >> /etc/profile
source /etc/profile
# 验证安装
java --version
安装完成后,将JDK复制到另一个Tomcat节点:
bash复制scp -r /usr/local/jdk-21.0.9/ root@web2:/usr/local/
scp /etc/profile root@web2:/etc/
经验分享:我习惯使用scp同步配置时先验证指纹,避免中间人攻击。第一次连接时会提示确认指纹,确认无误后再输入yes。
3.2 Tomcat安装与优化
选择Tomcat 11.0.x版本(兼容Servlet 5.0/JSP 3.0):
bash复制wget https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.15/bin/apache-tomcat-11.0.15.tar.gz
tar -zxf apache-tomcat-11.0.15.tar.gz -C /usr/local/
mv /usr/local/apache-tomcat-11.0.15 /usr/local/tomcat-11.0.15
# 配置环境变量
echo 'export CATALINA_HOME=/usr/local/tomcat-11.0.15
export PATH=$PATH:$CATALINA_HOME/bin' >> /etc/profile
source /etc/profile
将Tomcat同步到另一个节点:
bash复制scp -r /usr/local/tomcat-11.0.15/ root@web2:/usr/local/
scp /etc/profile root@web2:/etc/
3.3 服务启动与测试
启动Tomcat服务:
bash复制startup.sh
为区分两个节点,我们修改默认首页:
bash复制# 在web1执行
echo "web1 $(hostname -I)" > $CATALINA_HOME/webapps/ROOT/index.jsp
# 在web2执行
echo "web2 $(hostname -I)" > $CATALINA_HOME/webapps/ROOT/index.jsp
测试访问:
bash复制curl http://192.168.72.41:8080
curl http://192.168.72.42:8080
实用技巧:在生产环境中,建议配置Tomcat的server.xml优化线程池、连接器等参数。同时应该删除默认的/docs、/examples等应用,减少安全风险。
4. Nginx负载均衡配置
4.1 Nginx安装与基础配置
在两台负载均衡节点上安装Nginx:
bash复制dnf install -y nginx
配置负载均衡(master节点):
bash复制cat > /etc/nginx/conf.d/tomcat.conf <<'EOF'
upstream web {
server 192.168.72.41:8080;
server 192.168.72.42:8080;
}
server {
listen 80;
server_name 192.168.72.30;
location / {
proxy_pass http://web;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
将配置同步到backup节点:
bash复制scp /etc/nginx/conf.d/tomcat.conf root@backup:/etc/nginx/conf.d/
修改backup节点的server_name为192.168.72.32后启动服务:
bash复制systemctl start nginx
4.2 负载均衡测试
通过curl测试负载均衡效果:
bash复制for i in {1..10}; do curl -s http://192.168.72.30; done
应该能看到请求轮流分发到两个Tomcat节点。
性能调优建议:默认的轮询(round-robin)策略适合大多数场景。对于需要会话保持的应用,可以添加
ip_hash指令。此外,可以调整upstream中的weight参数实现加权轮询。
5. Keepalived高可用实现
5.1 Keepalived安装与配置
在两台负载均衡节点上安装Keepalived:
bash复制dnf install -y keepalived
配置master节点的keepalived.conf:
bash复制cat > /etc/keepalived/keepalived.conf <<'EOF'
global_defs {
router_id nginx1
}
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.72.100
}
track_script {
chk_nginx
}
}
EOF
创建Nginx健康检查脚本:
bash复制cat > /etc/keepalived/check_nginx.sh <<'EOF'
#!/bin/bash
count=$(ps -C nginx --no-header | wc -l)
if [ $count -eq 0 ]; then
systemctl start nginx
sleep 1
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then
systemctl stop keepalived
fi
fi
EOF
chmod +x /etc/keepalived/check_nginx.sh
将配置同步到backup节点并修改:
- 修改router_id为nginx2
- 修改state为BACKUP
- 修改priority为90
5.2 VIP配置与测试
启动Keepalived服务:
bash复制systemctl start keepalived
检查VIP绑定情况:
bash复制ip a show ens160
在master节点上应该能看到192.168.72.100绑定在ens160接口上。
修改Nginx配置,将server_name改为VIP地址:
bash复制sed -i 's/server_name .*/server_name 192.168.72.100;/' /etc/nginx/conf.d/tomcat.conf
systemctl restart nginx
测试VIP访问:
bash复制curl http://192.168.72.100
5.3 故障转移测试
- 在master节点停止Nginx:
bash复制systemctl stop nginx
- 观察VIP是否漂移到backup节点:
bash复制# 在backup节点执行
ip a show ens160
- 检查服务是否仍然可用:
bash复制curl http://192.168.72.100
重要提示:测试时建议在控制台同时监控两个节点的系统日志(
journalctl -f),可以清晰看到故障转移的过程和日志输出。
6. 常见问题与优化建议
6.1 典型问题排查
-
VIP无法绑定:
- 检查virtual_router_id是否冲突(同一局域网内应唯一)
- 确认防火墙未阻止VRRP协议(IP协议号112)
- 检查网络接口名称是否正确(ifconfig查看)
-
Nginx健康检查失败:
- 确认check_nginx.sh有执行权限(chmod +x)
- 检查脚本路径是否正确
- 查看/var/log/messages中的Keepalived日志
-
负载不均衡:
- 确认两个Tomcat节点都健康(检查Nginx的error_log)
- 考虑使用least_conn算法代替默认的轮询
6.2 生产环境优化建议
-
安全加固:
- 为VRRP配置更复杂的auth_pass
- 限制Nginx和Tomcat的管理接口访问
- 配置HTTPS加密传输
-
监控与告警:
- 监控VIP绑定状态
- 监控Nginx和Tomcat进程
- 设置Keepalived状态变化的告警
-
性能优化:
- 调整Nginx的worker_processes和worker_connections
- 配置Tomcat连接池和JVM参数
- 启用静态资源缓存
这套架构在我负责的多个电商系统中稳定运行,最高支撑过"双11"级别的流量冲击。它的优势在于简单可靠,各组件分工明确,扩展也很方便——当需要扩容时,只需增加Tomcat节点并更新Nginx配置即可。