Nginx + Tomcat 实现 负载均衡 和 动静分离群集
Posted 我一个月改一次名
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx + Tomcat 实现 负载均衡 和 动静分离群集相关的知识,希望对你有一定的参考价值。
目录
前言
动静分离群集 就是 静态的由 nginx 处理,动态的由Nginx 交给 Tomcat 处理。
Nginx 反向代理
一、Nginx 应用
Nginx 是一款非常优秀的 HTTP服务器软件
- 支持高达 50000 个并发连接数的响应
- 拥有强大的静态资源处理能力
- 运行稳定
- 内存、CPU等系统资源消耗非常低
目前很多大型网站都应用 Nginx 服务器作为后端网站程序的 反向代理 及 负载均衡器,用来提升整个站点的负载并发能力。
二、Nginx 负载均衡
2.1 负载均衡功能介绍
- Nginx 实现负载均衡 是 通过反向代理实现的
反向代理原理 如下图:
通过Nginx 反向代理的模块实现让 Nginx 接受客户端发来的请求,静态的由 Nginx 处理,如果是动态处理 由Nginx 再把请求转发给 Tomcat 处理。Tomcat 处理后返回的界面再交给Nginx ,Nginx 再交给用户。
Nginx 有七层反向代理(通过 http 或 udp 协议),和 四层反向代理(通过 IP + 端口进行转发)。
2.2 Nginx 负载均衡实现原理
Nginx配置反向代理的主要参数:
upstream 服务池名 {}
- 配置后端真实服务器池,以提供响应数据,服务池名:通过
IP:端口号
实现,如server 192.168.31.102:8080
。 proxy_pass http://服务池名
- 配置将访问请求 转发给 后端服务器池的服务器处理
2.3 Nginx 负载均衡模式:
● rr 轮循负载均衡模式:
每个请求按时间顺序逐一分配到不同的后端服务器,如果超过了最大失败次数后(max_fails,默认1),在失效时间内(fail_timeout,默认10秒),该节点失效权重变为0,超过失效时间后,则恢复正常,或者全部节点都为down后,那么将所有节点都恢复为有效继续探测,一般来说rr可以根据权重来进行均匀分配。
● 加权轮循
● least_conn 最少连接:
优先将客户端请求调度到当前连接最少的服务器。
● ip_hash 负载均衡模式:
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题,但是ip_hash会造成负载不均,有的服务请求接受多,有的服务请求接受少,所以不建议采用 ip_hash 模式,session 共享问题可用后端服务的 session 共享代替 nginx 的 ip_hash。
● fair(第三方)负载均衡模式:
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
● url_hash(第三方)负载均衡模式:
和 ip_hash 算法类似,是对每个请求按 url 的 hash 结果分配,使每个URL定向到一个同 一个后端服务器,但是也会造成分配不均的问题,这种模式后端服务器为缓存时比较好。
三、Nginx 动静分离实现原理
3.1 动静分离原理
- 服务端接收来自客户端的请求中,请求既有 静态资源 也有 动态资源,静态资源由 Nginx 提供服务,动态资源由 Nginx 转发至后端。
3.2 Nginx 静态处理优势
-
Nginx 处理静态页面的效率远高于 Tomcat 的处理能力
-
若 Tomcat 的请求量为1000次,则 Nginx 的请求量为6000次
-
Tomcat 每秒的吞吐量为0.6M,Nginx 的每秒吞吐量为3.6M
-
Nginx 处理静态资源的能力是 Tomcat 处理的6倍
-
以 Nginx 作为负载均衡器,Tomcat 作为应用服务器
-
七层反向代理
环境准备
主机 | 操作系统 | IP地址 | 所需软件 |
---|---|---|---|
Nginx 服务器 | CentOS7 | 192.168.31.101 | nginx-1.12.0.tar.gz |
Tomcat 服务器1 | CentOS7 | 192.168.31.102 | apache-tomcat-9.0.16.tar.gz jdk-8u201-linux-x64.rpm |
Tomcat 服务器2 | CentOS7 | 192.168.31.106 | apache-tomcat-9.0.16.tar.gz jdk-8u201-linux-x64.rpm |
3.3 配置七层反向代理
3.3.1 部署 Nginx 负载均衡服务器
Nginx 负载均衡服务器为 192.168.31.101
准备好虚拟机器之后:
下面是Nginx服务一键脚本,执行脚本即可部署、启动Nginx服务:
#!/bin/bash
#脚本说明:编译安装nginx服务
#注意:使用前请将nginx-1.12.0.tar.gz放入/opt目录下
#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
#安装所需开发包和编译环境、编译器
yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make
#创建程序用户,便于准确控制访问
useradd -M -s /sbin/nologin nginx
#解压安装包
cd /opt
tar zxvf nginx-1.12.0.tar.gz -C /opt/
#编译安装nginx;指定安装路径、指定用户名、组名、启用模块以支持统计状态
cd /opt/nginx-1.12.0/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-file-aio --with-http_gzip_static_module --with-http_flv_module --with-http_ssl_module
make && make install
#软链接便于系统识别nginx操作命令
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
#添加nginx系统服务
echo '[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecrReload=/bin/kill -s HUP $MAINPID
ExecrStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target' > /lib/systemd/system/nginx.service
#赋权及开启服务、开启开机自启
chmod 754 /lib/systemd/system/nginx.service
systemctl restart nginx.service
systemctl enable nginx.service
执行完一键部署nginx 后,查看nginx 服务已经开启了,部署成功。
3.3.2 部署两台 Tomcat 应用服务器
下面是Tomcat服务一键脚本,需要分别在 792.168.31.102 个 192.168.31.106 两台机器上分别执行。
执行前需要把对应的软件包放到 /opt/ 目录下:
#!/bin/bash
#安装Tomcat服务
#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
#安装JDK
cd /opt
rpm -ivh jdk-8u201-linux-x64.rpm
#设置JDK环境变量
echo 'export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$PATH' > /etc/profile.d/java.sh
source /etc/profile.d/java.sh
#安装并启动Tomcat
cd /opt
tar zxvf apache-tomcat-9.0.16.tar.gz
mv apache-tomcat-9.0.16 /usr/local/tomcat
/usr/local/tomcat/bin/startup.sh
192.168.31.102
192.168.31.106
3.3.3 动静分离配置
1)Tomcat 服务器1 配置
mkdir /usr/local/tomcat/webapps/test
vim /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test1 page</title>
</head>
<body>
<% out.println("动态页面 1:www.test1.com");%>
</body>
</html>
#修改配置文件,注意 Host name 名字是唯一的
vim /usr/local/tomcat/conf/server.xml
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true" />
</Host>
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
2)Tomcat 服务器2 配置
mkdir /usr/local/tomcat/webapps/test
vim /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test2 page</title>
</head>
<body>
<% out.println("动态页面 1:www.test2.com");%>
</body>
</html>
#修改配置文件
vim /usr/local/tomcat/conf/server.xml
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true" />
</Host>
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
netstat -natp | grep java
3)Nginx server 配置
#准备静态页面和静态图片
echo '<html><body><h1> this is Nginx static !</h1></body></html>' > /usr/local/nginx/html/index.html
mkdir /usr/local/nginx/html/static
cd /usr/local/nginx/html/static
#存放静态图片
vim /usr/local/nginx/conf/nginx.conf
......
http {
......
#gzip on;
#配置负载均衡的服务器列表,weight参数表示权重,权重越高,被分配到的概率越大
upstream tomcat_server {
server 192.168.31.102:8080 weight=1;
server 192.168.31.102:8080 weight=1;
server 192.168.31.102:8081 weight=1;
}
server {
listen 80;
server_name www.kgc.com;
charset utf-8;
#access_log logs/host.access.log main;
#配置Nginx处理动态页面请求,将 .jsp文件请求转发到Tomcat 服务器处理
location ~ .*\\.jsp$ {
proxy_pass http://tomcat_server;
#设置后端的Web服务器可以获取远程客户端的真实IP
##设定后端的Web服务器接收到的请求访问的主机名(域名或IP、端口),默认HOST的值为proxy_pass指令设置的主机名。如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来在反向代理服务器,如果后端有防攻击策略的话,那么机器就被封掉了。
proxy_set_header HOST $host;
##把$remote_addr赋值给X-Real-IP,来获取源IP
proxy_set_header X-Real-IP $remote_addr;
##在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#配置Nginx处理静态图片请求
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
root /usr/local/nginx/html/img;
#缓存十天
expires 10d;
}
location / {
root html;
index index.html index.htm;
}
}
}
如:
vim /usr/local/nginx/conf/nginx.conf
......
http {
......
#gzip on;
upstream tomcat_server {
server 192.168.31.102:8080 weight=1;
server 192.168.31.106:8080 weight=1;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#配置Nginx处理动态页面请求,将 .jsp 文件请求转发到Tomcat 服务器处理
location ~ .*\\.jsp$ {
proxy_pass http://tomcat_server;
#让后端服务器能获取到真实的用户的请求IP地址,不加的话只能是nginx的地址
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#配置Nginx处理静态图片请求
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
root /usr/local/nginx/html/img/;
expires 10d;
}
location / {
root html;
index index.html index.htm;
}
#重启nginx 服务
systemctl restart nginx.service
准备静态图片和资源
先测试走 nginx 静态处理的资源
测试负载均衡效果,不断刷新浏览器测试
浏览器访问 http://192.168.31.101/test/index.jsp
因为权重一样,所以会随机访问两个 tomcat 的任意一个界面
3.4 配置四层反向代理
在实验 3.3 的基础上对 Nginx 服务器进行修改,两台 Tomcat 不用动。
还原 192.168.31.101 重新安装nginx
需要在 nginx 配置中 添加 --with-stream
模块,然后再编译安装
#!/bin/bash
#脚本说明:编译安装nginx服务
#注意:使用前请将nginx-1.12.0.tar.gz放入/opt目录下
#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
#安装所需开发包和编译环境、编译器
yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make
#创建程序用户,便于准确控制访问
useradd -M -s /sbin/nologin nginx
#解压安装包
cd /opt
tar zxvf nginx-1.12.0.tar.gz -C /opt/
#编译安装nginx;指定安装路径、指定用户名、组名、启用模块以支持统计状态
cd /opt/nginx-1.12.0/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-file-aio --with-http_gzip_static_module --with-http_flv_module --with-http_ssl_module --with-stream
make && make install
#软链接便于系统识别nginx操作命令
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
#添加nginx系统服务
echo '[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFileNginx和tomcat实现负载均衡