Nginx+Tomcat负载均衡、动静分离群集方案

一、Tomcat简介

在现代 Web 服务架构中,Tomcat 和 Nginx 是两个至关重要的组件,负责处理用户请求并实现高性能的服务。本篇博客将深入探讨这些技术的原理和部署配置方法。

  • 最初是由Sun的软件构架师詹姆斯·邓肯·戴维森开发。
  • 安装Tomcat后,安装路径下面的目录和文件,是使用或者配置Tomcat的重要文件。

二、Nginx负载均衡原理

Nginx应用

  • 1、Nginx是一款非常优秀的HTTP服务器软件
    • 支持高达50 000个并发连接数的响应
    • 拥有强大的静态资源处理能力
    • 运行稳定
    • 内存、CPU等系统资源消耗非常低
  • 2、目前很多大型网站都应用Nginx服务器作为后端网站程序的反向代理及负载均衡器,提升整个站点的负载并发能力

Nginx实现负载均衡的原理主要通过以下几个关键步骤

负载均衡原理

反向代理原理

具体过程

  1. 接收请求:Nginx作为反向代理服务器,接收客户端的请求。
  2. 选择后端服务器:根据预先配置的负载均衡算法,Nginx选择一个后端服务器来处理请求。
  3. 转发请求:Nginx将接收到的请求转发给选定的后端服务器。
  4. 返回响应:后端服务器处理请求并生成响应,将响应发送回Nginx。
  5. 返回客户端:Nginx将接收到的响应返回给客户端。

当使用Nginx服务器作为前端时,可以配置Nginx来进行静态页面的处理,而将动态页面请求转发给后端的Tomcat服务器来处理。由于Tomcat是轻量级应用服务器,可能无法满足所有访问量,因此需要多台Tomcat服务器,并通过Nginx的配置权重来进行负载均衡,以确保请求能够被分发到不同的Tomcat服务器上。

Nginx配置反向代理的主要参数

  • upstream 服务池名{}
    • 配置后端服务器池,以提供响应数据
  • proxy pass http://服务池名
    • 配置将访问请求转发给后端服务器池的服务器处理

三、Nginx 负载均衡模式

  • 轮询(默认):

每个请求按时间顺序逐一分配到不同的后端服务器,如果超过了最大失败次数后(max_fails,默认1),在失效时间内(fail_timeout,默认10秒),该节点失效权重变为0,超过失效时间后,则恢复正常,或者全部节点都为down后,那么将所有节点都恢复为有效继续探测。

  • 加权轮询:

根据服务器的权重分配请求,权重越高的服务器获得更多的请求。优先将客户端请求调度到当前连接最少的服务器。

  • ip_hash :

每个请求按访问ip的hash哈希值结果分配,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用,可以解决session的问题。但是ip_hash如下问题:当后端服务器宕机后,session会丢失;来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载不均。

  • ●air(第三方):

按后端服务器的响应时间来分配请求,响应时间短的优先分配。需要安装upstream_fair模块才能实现。

  • url_hash(第三方):

基于用户请求的uri做hash。和ip_hash算法类似,是对每个请求按url的hash结果分配,使每个URL定向到同一个后端服务器,但是也会造成分配不均的问题,这种模式后端服务器为缓存时比较好,可以提高后端缓存服务器的效率。

session 共享问题还可以使用sticky_cookie_insert启用会话亲缘关系,基于cookie来判断,使来自同一客户端的请求被传递到一组服务器在同一台服务器。也可用后端服务的 session 共享代替 nginx 的 ip_hash(使用后端服务器自身通过相关机制保持session同步)。

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    sticky_cookie_insert srv_id expires=1h domain=www.xy101.com path=/;
}

#说明:需要引入第三方sticky模块才能实现;expires:设置浏览器中保持cookie的时间;domain:定义cookie的域;path:为cookie定义路径

Nginx 四层代理配置:

./configure --with-stream和http同等级:所以一般配置位置只在http上面一段设置,

stream {
    
    upstream appserver {
        server 192.168.80.100:8080 weight=1;
        server 192.168.80.101:8080 weight=1;
        server 192.168.80.101:8081 weight=1;
    }
    server {
        listen 8080;
        proxy_pass appserver;
    }
}

http {
......

四、Nginx动静分离原理

动静分离原理

服务端接收来自客户端的请求中,既有静态资源也有动态资源,静态资源由Nginx提供服务,动态资源Nginx转发至后端

Nginx静态处理优势

  • Nginx处理静态页面的效率远高于Tomcat的处理能力
  • 若Tomcat的请求量为1000次,则Nginx的请求量为6000次
  • Tomcat每秒的吞吐量为0.6M,Nginx的每秒吞吐量为3.6M
  • Nginx处理静态资源的能力是Tomcat处理的6倍

Nginx 服务器:192.168.80.10:80

Tomcat服务器1:192.168.80.100:80

Tomcat服务器2:192.168.80.101:8080 192.168.80.101:8081

4.1 部署Nginx 负载均衡器

systemctl stop firewalld
setenforce 0

#安装所需开发包和编译环境、编译器
yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make

#创建程序用户,便于准确控制访问
useradd -M -s /sbin/nologin nginx

#解压nginx文件
cd /opt
tar zxvf nginx-1.12.0.tar.gz -C /opt/

cd nginx-1.12.0/
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-file-aio \                                    #启用文件修改支持
--with-http_stub_status_module \                    #启用状态统计
--with-http_gzip_static_module \                    #启用 gzip静态压缩
--with-http_flv_module \                            #启用 flv模块,提供对 flv 视频的伪流支持
--with-http_ssl_module                                #启用 SSL模块,提供SSL加密功能
--with-stream                                        #启用 stream模块,提供4层调度
----------------------------------------------------------------------------------------------------------
./configure \
--prefix=/usr/local/nginx \                           # 指定安装目录为 /usr/local/nginx
--user=nginx \                                         # 指定运行 nginx 的用户为 nginx
--group=nginx \                                        # 指定运行 nginx 的用户组为 nginx
--with-file-aio \                                      # 启用文件异步IO支持
--with-http_stub_status_module \                       # 启用 HTTP Stub 状态模块,用于获取 nginx 的运行状态
--with-http_gzip_static_module \                       # 启用 HTTP gzip 静态压缩模块,用于对静态文件进行 gzip 压缩
--with-http_flv_module \                               # 启用 HTTP FLV 模块,提供对 FLV 视频的伪流支持
--with-http_ssl_module \                               # 启用 HTTP SSL 模块,提供 SSL 加密功能
--with-stream                                           # 启用 Stream 模块,提供 4 层调度功

#编译及安装
make && make install

#软链接便于系统识别nginx操作命令
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/


#添加nginx系统服务以便系统管理启动、停止、重启
vim /lib/systemd/system/nginx.service
[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

#赋权及开启服务、开启开机自启
chmod 754 /lib/systemd/system/nginx.service
systemctl start nginx.service
systemctl enable nginx.service

4.2 nginx一键部署脚本

#!/bin/bash
#======编译安装nginx服务======
#安装所需开发包和编译环境、编译器
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/

#指定安装路径、指定用户名、组名、启用模块以支持统计状态
cd 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
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/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 daemon-reload
systemctl start nginx
systemctl enable nginx

五、部署Tomcat

1.部署2台Tomcat 应用服务器(两台相同操作)

systemctl stop firewalld
setenforce 0

#解压安装JDK
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/

#设置JDK环境变量
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_91
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:$PATH

#刷新配置文件,使配置生效
source /etc/profile

#解压tomcat
tar zxvf apache-tomcat-8.5.16.tar.gz

#将文件移动至/usr/local/下并重命名
mv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat

#tomcat启动关闭脚本位置
/usr/local/tomcat/bin/shutdown.sh 
/usr/local/tomcat/bin/startup.sh

#重新加载服务,并开启,查看是否成功启动
/usr/local/tomcat/bin/startup.sh 
lsof -i:8080
netstat -ntap | grep 8080

六、配置Nginx动静分离

6.1.动静分离配置

(1)Tomcat1 server 配置
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>   #指定为 test1 页面
</head>
<body>
<% out.println("动态页面 1,http://www.test1.com");%>
</body>
</html>

(2)Tomcat1 server 配置
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>   #指定为 test2 页面
</head>
<body>
<% out.println("动态页面 2,http://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>

这段配置是用来定义 Tomcat 服务器的主机(Host)配置。在这里,<Host> 元素定义了 Tomcat 主机的一些属性,其中包括:

  • name="localhost": 定义了主机的名称为 "localhost"。
  • appBase="webapps": 指定了存放 Web 应用程序的基本目录为 "webapps",这是 Tomcat 默认的应用程序部署目录。
  • unpackWARs="true": 表示当部署 WAR 文件时,自动将其解压缩。
  • autoDeploy="true": 表示自动部署 WAR 文件,如果设置为 true,则 Tomcat 会监视 appBase 目录中的新应用程序并自动部署它们。
  • xmlValidation="false"xmlNamespaceAware="false": 关闭对 web.xml 文件的 XML 验证,以及关闭对 XML 命名空间的感知。

<Host> 元素内部,<Context> 元素用于定义单个 Web 应用程序的上下文配置。在这里,它指定了一个名为 "test" 的Web应用程序的部署路径为根路径(""),并且启用了自动重载(reloadable="true")。

#重启两台服务
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh

6.2Nginx server 配置

#准备静态页面和静态图片
echo '<html><body><h1>这是默认目录静态页面</h1></body></html>' > /usr/local/nginx/html/index.html
mkdir /usr/local/nginx/html/kiki

#编辑nginx配置文件
​vim /usr/local/nginx/conf/nginx.conf

......
http {
......
#gzip on;
#后端负载服务器的地址
upstream tomcat_server {
  server 192.168.1.20:8080 weight=1;
  server 192.168.1.30:8080 weight=1;
}

server {
  listen 80;
  server_name www.tong.com;

  charset utf-8;

  #access_log logs/host.access.log main;

#配置Nginx处理动态页面请求,将 .jsp文件请求转发到Tomcat 服务器处理
  location ~ .*.jsp$ {
    proxy_pass http://tomcat_server;  
    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/kiki;
    expires 10d;
  }
  
  location / {
    root html;
    index index.html index.htm;
  }
......

七、总结

Nginx与Tomcat的结合可以实现负载均衡和动静分离,同时构建一个高性能的群集系统。

  1. 负载均衡:Nginx作为反向代理服务器,可以将请求分发到多个Tomcat服务器上,以实现负载均衡。通过配置Nginx的upstream模块,可以指定多个Tomcat服务器作为后端服务器,Nginx会根据一定的策略(如轮询、权重等)将请求分发给这些Tomcat服务器,从而提高整个系统的吞吐量和可用性。

  2. 动静分离:Nginx可以将动态请求(如JSP、Servlet等)和静态请求(如HTML、CSS、JavaScript等)分开处理。静态资源由Nginx直接响应,避免了Tomcat的负担,提高了静态资源的访问速度;动态请求则转发至Tomcat服务器进行处理,保证了动态内容的正确性。

  3. 群集系统:通过将多个Tomcat服务器与Nginx结合,可以构建一个高性能的群集系统。Nginx负责接收和分发请求,而Tomcat服务器则负责处理业务逻辑。当集群中的某个Tomcat发生故障时,Nginx可以自动将请求转发到其他正常运行的Tomcat服务器上,保证了系统的稳定性和可靠性。

总之,Nginx与Tomcat结合可以实现负载均衡、动静分离和构建高性能的群集系统,为Web应用程序提供了强大的性能和可用性支持。

相关推荐
ajsbxi4 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
尢词16 小时前
SpringMVC
java·spring·java-ee·tomcat·maven
清风百草16 小时前
【04】【Maven项目热部署】将Maven项目热部署到远程tomcat服务器上
tomcat·maven项目热部署
JustCouvrir1 天前
macOS|前端工程部署到Nginx服务器
服务器·前端·nginx
AlbertS1 天前
使用 Let’s Encrypt 获取免费SSL证书
nginx·免费·centos7·ssl证书·let’s encrypt
航月1 天前
FTP、ISCSI、CHRONY、DNS、NFS、DOCKER、MARIADB、NGINX、PHP、CA各服务开启方法
nginx·docker·mariadb
IT-民工211101 天前
nginx监控指标有哪些
运维·nginx
蒋桐城1 天前
Tomcat 启动卡住,日志显示 At least one JAR was scanned for TLDs yet contained no TLDs.
java·tomcat
qiaosaifei1 天前
SpringBoot项目中替换指定版本的tomcat
spring boot·后端·tomcat
田猿笔记1 天前
RabbitMQ 实现消息队列负载均衡
分布式·rabbitmq·负载均衡