案例:Nginx + Tomcat集群(负载均衡 动静分离)

目录

案例

案例环境

案例步骤

部署Tomcat服务器

部署Nginx服务器

实现负载均衡和读写分离

日志控制


案例

案例环境

|----------------|----------------|---------------|
| 操作系统 | IP 地址 | 角色 |
| CentOS | 192.168.10.101 | Nginx服务器(调度器) |
| CentOS | 192.168.10.102 | Tomcat服务器① |
| CentOS | 192.168.10.103 | Tomcat服务器② |
| Windows虚拟机或宿主机 | | 浏览器测试 |

需求:静态请求交给Nginx解析,动态请求交给2个Tomcat服务器实现动静分离和负载均衡

以及日志的控制

假如有DDOS等网络攻击,服务器的连接数会被耗尽,需要获取真实客户端的地址

DDOS:分布式拒绝服务攻击


案例步骤

部署Tomcat服务器

因为102和103都是作为Tomcat服务器,部署的大致步骤相同,这里我们只开启102和103的会话同步

分别导入tomcat源码软件包到102和103主机

在102(Tomcat服务器①)操作

为了方便实验关闭防火墙和内核安全机制

tomcat是java开发的,这里我们需要在系统上安装java,确保开发环境一致

这里yum安装的java没有指定版本,安装的java版本是1.8的,可能仅适用于本次案例

bash 复制代码
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install java

tomcat是解压即用的,不需要编译和安装。

移动到/usr/local/下方便使用

bash 复制代码
[root@localhost ~]# tar zxvf apache-tomcat-9.0.8.tar.gz
[root@localhost ~]# mv apache-tomcat-9.0.8 /usr/local/tomcat9

在根目录下创建一个用来存放网页文件的目录

在该目录下添加动态内容和静态内容,以达到更好的测试效果

bash 复制代码
[root@localhost webapps]# mkdir -p /web/webapp1
[root@localhost webapps]# cd /web/webapp1/
[root@localhost webapp1]# vim index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
     <title>JSP test1 page</title>   </head>
   <body>
     <% out.println("动态页面 1,http://www.test1.com");%>
   </body>
   <body>
    <div>动态页面的图片 1</div><br><img src="logo.jpg">
   </body>
</html>

在103(Tomcat服务器②)操作

为了实现调度的效果,暂时关闭会话同步,来到103把其中的文本内容改一下

bash 复制代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 
<html>   
<head>
     <title>JSP test2 page</title>
</head>
   <body>
     <% out.println("动态页面 2,http://www.test2.com");%>
   </body> 
   <body> 
    <div>动态页面的图片 2</div><br><img src="logo.jpg"> 
   </body> 
</html>

在102(Tomcat服务器①)操作

开启会话同步

打开tomcat配置文件

在第150行,Host单元中添加Context标签,指定网页文件的位置

bash 复制代码
[root@localhost tomcat9]# vim /usr/local/tomcat9/conf/server.xml
<Context docBase="/web/webapp1" path="" />

保存并退出,启动tomcat

bash 复制代码
[root@localhost ~]# /usr/local/tomcat9/bin/startup.sh

使用宿主机的浏览器测试,访问两个Web服务器的IP+端口号。结果如下,动态和静态的内容都显示出来了

图像、音频、视频之类的资源我们交给Nginx去解析,所以现在看不到图片是正常的


部署Nginx服务器

在101(Nginx服务器)操作

首先导入Nginx的源码软件包,准备安装

为了方便实验,关闭防火墙和内核安全机制

再安装Nginx依赖软件包,创建程序用户

bash 复制代码
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install pcre-devel zlib-devel gcc*
[root@localhost ~]# useradd -M -s /sbin/nologin nginx

解压Nginx源码包,进入解压目录,运行configure脚本,指定安装参数,编译(make)、安装(make install)

bash 复制代码
[root@localhost ~]# tar zxvf nginx-1.12.0.tar.gz
[root@localhost ~]# cd nginx-1.12.0
[root@localhost nginx-1.12.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
[root@localhost nginx-1.12.0]# make && make install

优化调用命令的方式,创建软链接到命令目录下,然后使用nginx -t测试是否能正常调用命令

bash 复制代码
[root@localhost nginx-1.12.0]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
[root@localhost ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

cd进入Nginx存放网页文件的目录,删除index.html文件中的内容,替换为下方代码块的内容

bash 复制代码
[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# vim index.html
<body>
<h1>静态页面</h1>
</body>

因为我们的网页有中文,所以打开Nginx配置文件,在第39行指定字符集为utf8,然后保存并退出

bash 复制代码
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
charset utf8;

启动nginx服务,结果如下图

bash 复制代码
[root@localhost ~]# nginx

实现负载均衡和读写分离

刚才说了在这个案例的环境中,图像等静态资源由Nginx负责解析,那么相应的要实现动静分离

cd进入Nginx存放网页文件的目录,在该目录下创建一个存放图片资源的子目录,进入该目录,把之前在tomcat指定的logo.jpg导入进该目录下

bash 复制代码
[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# mkdir img
[root@localhost html]# cd img/

除此之外,还需要修改配置文件来实现动静分离

返回上一级目录知道nginx根目录,打开配置文件

bash 复制代码
[root@localhost img]# cd ..
[root@localhost html]# cd ..
[root@localhost nginx]# vim conf/nginx.conf

在第34行,添加upstream单元来配置负载均衡

再往下隔一个location单元,添加2个location单元实现读写分离(看下图)

下方代码表示nginx会将到达的请求按照权重分发到两台Tomcat服务器上,权重值(weight)越高,处理的请求越多

bash 复制代码
    upstream mytomcat {
        server 192.168.10.102:8080;
        server 192.168.10.103:8080;
    }
    # 省略...
    location ~ .*\.jsp$ {
        proxy_set_header HOST $host;
        proxy_pass http://mytomcat;
    }

    location ~ .*\.(jpg|png|gif)$ {
        root /usr/local/nginx/html/img;
        expires 30d;
    }

|------------------------------|------------------------------------------------------------------|
| 参数 | 说明 |
| proxy_set_header HOST $host; | 把原http请求中的Header中的Host字段放到转发的请求报文里,后端的web服务器利用这个host判断请求的是哪个虚拟主机 |

  • ~:不区分大小写
  • .*.\.jsp$:nginx匹配所有以.jsp结尾的请求,并将它们转发到定义的mytomcat后端服务器组中的某个Tomcat服务器处理。
  • .*\.(jpg|png|gif)$:这个配置用于处理静态图片文件。对于这些文件的请求,nginx会直接从指定的目录中提供,并设置响应头以便客户端进行缓存。
  • expires 30d:缓存时间为30天

由于修改了配置文件,需要重启服务使其生效,使用宿主机的浏览器访问192.168.10.101/index.jsp,此时就可以解析图片了,效果如下图

bash 复制代码
[root@localhost nginx]# nginx -s stop
[root@localhost nginx]# nginx

日志控制

在102(Tomcat服务器①)操作

如果此时查看Tomcat的访问日志,可以看到访问的IP都是代理服务器的IP

那么我们需要把这些源IP改为客户端的真实IP,以便Tomcat的访问日志能够详细记录

bash 复制代码
[root@localhost ~]# tail /usr/local/tomcat9/logs/localhost_access_log.2024-08-08.txt 
192.168.10.101 - - [08/Aug/2024:10:10:17 +0800] "GET /index.jsp HTTP/1.0" 200 215
192.168.10.101 - - [08/Aug/2024:10:10:18 +0800] "GET /index.jsp HTTP/1.0" 200 215
192.168.10.101 - - [08/Aug/2024:10:10:19 +0800] "GET /index.jsp HTTP/1.0" 200 215

在101(Nginx服务器)操作

打开配置文件,可以在location单元中设置对应参数来改变tomcat访问日志中的源IP

bash 复制代码
location ~ .*\.jsp$ {
            proxy_set_header HOST $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Client-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass  http://myTomcat;
        }

|--------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| 参数 | 说明 |
| proxy_set_header X-Real-IP remote_addr; | 使用remote_addr变量获得用户的真实ip 如果有多个代理,$remote_addr一般设置在第一个代理服务器上。 当一个请求通过多个代理服务器时,用户的IP将会被代理服务器IP覆盖 |
| proxy_set_header Client-IP $remote_addr; | 获取客户端ip地址 |
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | 从客户的真实ip为起点,穿过多层代理的proxy ,最终到达web服务器,都会记录下来。 所以在获取用户真实ip的时候,最后一个nginx配置此变量,用来获取客户端的ip地址 适合多层代理的场景 |

在102、103(Tomcat服务器①②)操作

打开Tomcat配置文件

在第162行添加代理服务器定义的变量

bash 复制代码
[root@localhost ~]# vim /usr/local/tomcat9/conf/server.xml
pattern="%{X-Real-IP}i %h %l %u %t &quot;%r&quot; %s %b" />
  • i:请求头

然后重启Tomcat服务

bash 复制代码
[root@localhost ~]# /usr/local/tomcat9/bin/shutdown.sh 
[root@localhost ~]# /usr/local/tomcat9/bin/startup.sh 

然后查看访问日志,就可以看到客户端的真实IP被加到开头了

bash 复制代码
[root@localhost ~]# tail /usr/local/tomcat9/logs/localhost_access_log.2024-08-08.txt 

192.168.10.1 192.168.10.101 - - [08/Aug/2024:11:02:52 +0800] "GET /index.jsp HTTP/1.0" 200 215
192.168.10.1 192.168.10.101 - - [08/Aug/2024:11:02:52 +0800] "GET /index.jsp HTTP/1.0" 200 215
192.168.10.1 192.168.10.101 - - [08/Aug/2024:11:02:52 +0800] "GET /index.jsp HTTP/1.0" 200 215
相关推荐
WalkingWithTheWind~几秒前
Linux搭建Nginx直播流媒体服务RTMP/RTSP转Http-flv视频浏览器在线播放/Vue/Java/ffmpeg
java·linux·nginx·ffmpeg·vue·http-flv·rtsp
青春:一叶知秋11 分钟前
Reactor模型说明
运维·服务器
粉032143 分钟前
Keeppalived 实现Nginx 的高可用集群
java·服务器·nginx
和舒貌2 小时前
Linux系统编程基础详解
linux·运维·服务器·基础
晚秋大魔王2 小时前
windwos与linux环境下Iperf3带宽测试工具的安装、使用
网络·iperf3·带宽测试
多敲代码防脱发2 小时前
Spring框架基本使用(Maven详解)
java·网络·后端·spring·maven
Jack魏3 小时前
Linux MySQL 8.0.29 忽略表名大小写配置
linux·mysql·mysql8·mysql常见问题
wssswsss3 小时前
docker容器网络配置及常用操作
网络·docker·容器
ctrigger3 小时前
AI回答:Linux C/C++编程学习路线
linux·c语言·c++
RFID舜识物联网3 小时前
RFID测温技术:电力设备安全监测的新利器
网络·人工智能·嵌入式硬件·物联网·安全