使用软件:vmware
第一步
搭建服务器:四台alma9
| 服务器角色 | 主机名 | IP地址 | 安装软件 | 用途 |
|---|---|---|---|---|
| 负载均衡器 | nginx-server | 192.168.111.10 | Nginx | 接收所有请求,分发静态/动态流量 |
| Tomcat节点1 | tomcat1 | 192.168.111.11 | JDK + Tomcat | 处理动态JSP请求 |
| Tomcat节点2 | tomcat2 | 192.168.111.12 | JDK + Tomcat | 处理动态JSP请求 |
| Tomcat节点3 | tomcat3 | 192.168.111.13 | JDK + Tomcat | 处理动态JSP请求 |
第二步:设置VMware虚拟网络
- 点击菜单栏的 “编辑” -> “虚拟网络编辑器”
- 找到
VMnet8(NAT模式)。 - 查看下方的“子网IP”和“子网掩码”,确认与规划的网段一致。
- 点击 “NAT设置” 按钮,在弹出的窗口中查看网关IP
- 取消勾选 “使用本地DHCP服务将IP地址分配给虚拟机”,后面自己手动配置。
- 保存

第三步:配置Windows宿主机虚拟网卡
在宿主机的网络设配器中找到vm8的虚拟网卡,我下图的以太网4就是vm8,只是命名问题而已,然后打开ipv4协议,把IP地址改为: 192.168.111.1 子网掩码: 255.255.255.0 网关不用填,dns自动获取就行。

第四步:配置四台AlmaLinux虚拟机
先在虚拟机设置中把四台服务器的网络适配器改成自定义vm8,如下图

然后依次登录到四台虚拟机中,修改它们的网卡配置文件,把IP固定下来
以al1(nginx-server)做示范
先是 nmcli con show #查看网卡名

nmcli connection mod ens33 ipv4.method manual ipv4.addresses 192.168.111.10/24 ipv4.gateway 192.168.111.2 ipv4.dns “114.114.114.114 8.8.8.8” autoconnect yes #配置对应的ip地址,子网掩码,网关和dns
然后 nmcli con up ens33 #重启一下

ping 192.168.111.2 ip a ping 192.168.111.10
然后随手测试配置是否生效和ping的通不,其他的三台也大致是这个操作。


第五步:验证网络互通
分别在几台服务器上相互ping一下是否能通



如上图,没有问题,然后在ping一下外网,如ping www.baidu.com诸如此类都行
接下来是正式准备了
一、环境准备(所有节点)
后续为了方便我用的是moba连接,

# 关闭防火墙和SELinux systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config # 更新系统 dnf update -y # 安装常用工具 dnf install -y vim wget curl net-tools tar


二、Tomcat节点配置(三台服务器)
2.1 安装JDK
dnf install -y java-11-openjdk java-11-openjdk-devel #安装

java -version javac -version #验证安装
# 设置JAVA_HOME
echo "export JAVA_HOME=/usr/lib/jvm/java-11-openjdk" >> /etc/profile
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile
source /etc/profile
echo $PATH
如下图,添加成功

2.2 下载安装Tomcat 9
这里我用的自己的包,

tar -zxvf apache-tomcat-9.0.52.tar.gz -C /usr/local/ #安装tomcat
先改名mv apache-tomcat-9.0.52 tomcat

2.3 创建Tomcat用户
# 创建tomcat用户 useradd -r -s /sbin/nologin tomcat # 修改目录所有者 chown -R tomcat:tomcat /usr/local/tomcat

2.4 配置tomcat环境变量
cat >> /etc/profile << ‘EOF’
export CATALINA_HOME=/usr/local/tomcat
export PATH=$PATH:$CATALINA_HOME/bin
EOF
2.5创建测试JSP页面(区分三台服务器)
在 tomcat1 (192.168.111.11) 上执行:
mkdir -p /usr/local/tomcat/webapps/ROOT
cat > /usr/local/tomcat/webapps/ROOT/index.jsp << 'EOF'
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<title>Tomcat节点1</title>
</head>
<body>
<h1>Tomcat Server 1</h1>
<p>服务器IP: 192.168.111.11</p>
<p>会话ID: <%= session.getId() %></p>
<p>当前时间: <%= new java.util.Date() %></p>
</body>
</html>
EOF

另外两个节点也只是服务器和节点123的区别
2.6创建静态测试页面
cat > /usr/local/tomcat/webapps/ROOT/static.html << 'EOF'
<html>
<head>
<title>静态页面测试</title>
<style>
body { font-family: Arial; margin: 40px; }
.static { color: green; font-weight: bold; }
</style>
</head>
<body>
<h1 class="static">这是一个静态HTML页面</h1>
<p>这个页面应该由Nginx直接返回,不会被转发到Tomcat</p>
<p>访问时间: <span id="time"></span></p>
<script>
document.getElementById('time').innerText = new Date().toLocaleString();
</script>
</body>
</html>
EOF
2.7 启动Tomcat
# 在三台服务器上分别启动
就是进入到/usr/local/tomcat/bin目录下,然后执行startup.sh
随后
netstat -tnlp | grep 8080
如下图:

随后在宿主机网页访问:如下图可以看到都成功了



2.8 创建Tomcat系统服务
[root@tomcat1 bin]# cat > /etc/systemd/system/tomcat.service << ‘EOF’
[Unit]
Description=Apache Tomcat 9 Web Application Container
After=network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/local/jdk11
Environment=CATALINA_HOME=/usr/local/tomcat
Environment=CATALINA_BASE=/usr/local/tomcat
Environment=CATALINA_PID=/usr/local/tomcat/temp/tomcat.pid
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
EOF
三、Nginx负载均衡器配置
3.1 安装Nginx
dnf install -y nginx #安装
systemctl start nginx #启动
systemctl enable nginx #开机自取
nginx -v #验证
如下图,没有问题

3.2 配置负载均衡与动静分离
# 备份原配置
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
# 编辑主配置文件
vim /etc/nginx/nginx.conf
完整配置如下:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
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;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 开启gzip压缩
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
# 定义Tomcat服务器集群(负载均衡池)
upstream tomcat_cluster {
# 负载均衡算法:默认轮询(rr)
# weight参数:权重越高,分配的请求越多
server 192.168.111.11:8080 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.111.12:8080 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.111.13:8080 weight=1 max_fails=3 fail_timeout=30s;
# 启用保持连接(提高性能)
keepalive 32;
}
# 第一个虚拟主机:动静分离配置
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# 字符集设置
charset utf-8;
# 动静分离关键配置
# 1. 静态资源由Nginx直接处理
location ~* \.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|css|js|woff|woff2|ttf|svg|eot)$ {
root /usr/share/nginx/html;
expires 30d;
add_header Cache-Control "public, no-transform";
access_log off;
# 如果静态文件不存在,则交给Tomcat处理(可选)
try_files $uri @tomcat;
}
# 2. 动态请求转发给Tomcat集群
location / {
# 如果是JSP请求,直接转发
if ($uri ~* \.jsp$) {
proxy_pass http://tomcat_cluster;
break;
}
# 默认也转发给Tomcat(根据实际需求调整)
proxy_pass http://tomcat_cluster;
}
# 3. 专门处理JSP请求的转发规则
location @tomcat {
proxy_pass http://tomcat_cluster;
# 设置代理请求头(重要)
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_set_header X-Forwarded-Proto $scheme;
# 连接超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 启用keepalive
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# 4. 状态监控页面(用于查看负载均衡状态)
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.111.0/24; # 允许内网访问
deny all;
}
# 错误页面配置
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
3.3 创建静态资源目录
mkdir -p /usr/share/nginx/html # 在 nginx-server 上创建静态文件目录
# 创建测试静态文件
cat > /usr/share/nginx/html/test.html << 'EOF'
<html>
<head>
<title>Nginx静态页面</title>
</head>
<body>
<h1>这是Nginx直接提供的静态页面</h1>
<p>服务器IP: 192.168.111.10</p>
<p>当前时间: <span id="time"></span></p>
<script>document.getElementById('time').innerText = new Date();</script>
</body>
</html>
EOF
# 创建CSS测试文件
mkdir -p /usr/share/nginx/html/css
cat > /usr/share/nginx/html/css/style.css << 'EOF'
body { font-family: Arial, sans-serif; margin: 40px; }
h1 { color: #333; }
p { line-height: 1.6; }
EOF
# 创建JS测试文件
mkdir -p /usr/share/nginx/html/js
cat > /usr/share/nginx/html/js/script.js << 'EOF'
console.log("静态JS文件由Nginx直接提供");
EOF
3.4 验证配置并重启
# 测试配置文件语法
nginx -t 如下语法没有问题

systemctl restart nginx
systemctl status nginx

四、测试验证
4.1 测试负载均衡功能
curl http://192.168.111.10/index.jsp curl http://192.168.111.10/index.jsp curl http://192.168.111.10/index.jsp curl http://192.168.111.10/index.jsp
就这一步碰到了一个让我卡了整整半小时的坑

[root@al1 local]# curl -v http://192.168.111.10/index.jsp 2>&1 | grcurl -v http://192.168.111.10/index.jsp 2>&1 | grep -i “host” > Host: 192.168.111.10 * Connection #0 to host 192.168.111.10 left intact org.apache.tomcat.util.http.parser.HttpParser.readHostDomainName(HttpParser.java:870) org.apache.tomcat.util.http.parser.Host.parse(Host.java:71) org.apache.tomcat.util.http.parser.Host.parse(Host.java:45) org.apache.coyote.AbstractProcessor.parseHost(AbstractProcessor.java:298)
后面查阅资料最后修改了nginx.conf的配置
[root@al1 local]# cat /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 {
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;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Tomcat集群
upstream tomcat_cluster {
server 192.168.111.11:8080;
server 192.168.111.12:8080;
server 192.168.111.13:8080;
keepalive 32;
}
server {
listen 80;
server_name _;
location ~* \.(html|htm|gif|jpg|png|css|js)$ {
root /usr/share/nginx/html;
expires 30d;
}
location / {
proxy_pass http://tomcat_cluster;
proxy_set_header Host "";
proxy_set_header X-Real-IP $remote_addr;
proxy_next_upstream off;
}
}
}
以上是最终精简模式,然后再测试

终于成功了
4.2 测试动静分离功能
# 1. 测试静态文件(应该由Nginx直接返回) curl -I http://192.168.111.10/test.html curl -I http://192.168.111.10/css/style.css curl -I http://192.168.111.10/js/script.js # 2. 测试动态文件(应该转发到Tomcat) curl -I http://192.168.111.10/index.jsp


通过响应头判断:
- 静态文件:
Server: nginx/版本号 - 动态文件:通过X-Forwarded-For等头信息确认转发
4.3 浏览器访问测试
- 访问静态页面:
http://192.168.111.10/test.html - 访问动态页面:
http://192.168.111.10/index.jsp
都测试成功了
五、负载均衡算法调优 (补充内容)
5.1 加权轮询(性能不均衡的服务器)
upstream tomcat_cluster {
server 192.168.111.11:8080 weight=3; # 高性能服务器
server 192.168.111.12:8080 weight=2;
server 192.168.111.13:8080 weight=1; # 低性能服务器
}
5.2 IP哈希(保持会话)
upstream tomcat_cluster {
ip_hash; # 同一IP始终访问同一台后端
server 192.168.111.11:8080;
server 192.168.111.12:8080;
server 192.168.111.13:8080;
}
5.3 最少连接
upstream tomcat_cluster {
least_conn; # 优先转发给连接数最少的后端
server 192.168.111.11:8080;
server 192.168.111.12:8080;
server 192.168.111.13:8080;
}
六、故障测试
6.1 模拟Tomcat节点宕机
while true; do
curl -s http://192.168.111.10/index.jsp | grep "服务器IP"
sleep 1
done 先是持续请求
然后在tomcat2(192.168.111.12)上/usr/local/tomcat/bin/shutdown.sh

可以看到后面12停止后,就不再有了,但是访问依旧正常
发表回复