目录
案例
案例环境
案例步骤
部署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的,可能仅适用于本次案例
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install java
tomcat是解压即用的,不需要编译和安装。
移动到/usr/local/下方便使用
[root@localhost ~]# tar zxvf apache-tomcat-9.0.8.tar.gz
[root@localhost ~]# mv apache-tomcat-9.0.8 /usr/local/tomcat9
在根目录下创建一个用来存放网页文件的目录
在该目录下添加动态内容和静态内容,以达到更好的测试效果
[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把其中的文本内容改一下
<%@ 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标签,指定网页文件的位置
[root@localhost tomcat9]# vim /usr/local/tomcat9/conf/server.xml
<Context docBase="/web/webapp1" path="" />
保存并退出,启动tomcat
[root@localhost ~]# /usr/local/tomcat9/bin/startup.sh
使用宿主机的浏览器测试,访问两个Web服务器的IP+端口号。结果如下,动态和静态的内容都显示出来了
图像、音频、视频之类的资源我们交给Nginx去解析,所以现在看不到图片是正常的
部署Nginx服务器
在101(Nginx服务器)操作
首先导入Nginx的源码软件包,准备安装
为了方便实验,关闭防火墙和内核安全机制
再安装Nginx依赖软件包,创建程序用户
[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)
[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测试是否能正常调用命令
[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文件中的内容,替换为下方代码块的内容
[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# vim index.html
<body>
<h1>静态页面</h1>
</body>
因为我们的网页有中文,所以打开Nginx配置文件,在第39行指定字符集为utf8,然后保存并退出
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
charset utf8;
启动nginx服务,结果如下图
[root@localhost ~]# nginx
实现负载均衡和读写分离
刚才说了在这个案例的环境中,图像等静态资源由Nginx负责解析,那么相应的要实现动静分离
cd进入Nginx存放网页文件的目录,在该目录下创建一个存放图片资源的子目录,进入该目录,把之前在tomcat指定的logo.jpg导入进该目录下
[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# mkdir img
[root@localhost html]# cd img/
除此之外,还需要修改配置文件来实现动静分离
返回上一级目录知道nginx根目录,打开配置文件
[root@localhost img]# cd ..
[root@localhost html]# cd ..
[root@localhost nginx]# vim conf/nginx.conf
在第34行,添加upstream单元来配置负载均衡
再往下隔一个location单元,添加2个location单元实现读写分离(看下图)
下方代码表示nginx会将到达的请求按照权重分发到两台Tomcat服务器上,权重值(weight)越高,处理的请求越多
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,此时就可以解析图片了,效果如下图
[root@localhost nginx]# nginx -s stop
[root@localhost nginx]# nginx
日志控制
在102(Tomcat服务器①)操作
如果此时查看Tomcat的访问日志,可以看到访问的IP都是代理服务器的IP
那么我们需要把这些源IP改为客户端的真实IP,以便Tomcat的访问日志能够详细记录
[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
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行添加代理服务器定义的变量
[root@localhost ~]# vim /usr/local/tomcat9/conf/server.xml
pattern="%{X-Real-IP}i %h %l %u %t "%r" %s %b" />
- i:请求头
然后重启Tomcat服务
[root@localhost ~]# /usr/local/tomcat9/bin/shutdown.sh
[root@localhost ~]# /usr/local/tomcat9/bin/startup.sh
然后查看访问日志,就可以看到客户端的真实IP被加到开头了
[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