Nginx + Tomcat 负载均衡、动静分离

前言

Tomcat简介

最初是由Sun的软件构架师詹姆斯·邓肯·戴维森开发

安装Tomcat后,安装路径下面的目录和文件,是使用或者配置Tomcat的重要文件

Nginx 应用

Nginx是一款非常优秀的HTTP服务器软件

(1)支持高达50 000个并发连接数的响应

(2)拥有强大的静态资源处理能力

(3)运行稳定

(4)内存、CPU等系统资源消耗非常低

目前很多大型网站都应用Nginx服务器作为后端网站程序的反向代理及负载均衡器,提升整个站点的负载并发能力

一.Nginx 负载均衡

1.实现原理

通过反向代理实现,还可以将nginx接收到的请求转发给多个后端应用服务器处理

2.反向代理原理

将Nginx接收到的请求转发给其它应用服务器处理

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

upstream 服务池名 { }

配置后端服务器池,以提供响应数据

proxy_pass http://服务池名

配置将访问请求转发给后端服务器池的服务器处理

upstream框架中,参数的含义

|--------------|--------------------------------------------------------------------|
| weight | 服务访问的权重,默认是1 |
| max_conns | server的最大并发连接数,仅作用于单worker进程,默认是0,表示没有限制 |
| max _fails | 在fail timeout时间段内,最大的失败次数,当达到最大失败时,会在failtimeout秒内这台server不允许再次被选择 |
| fail timeout | 单位为秒,默认10秒 |

4.动静分离的概念

静态页面请求,由nginx自行处理并响应;动态页面请求,则nginx通过反向代理转发给后端应用服务器处理

5.Nginx 静态处理优势

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

6.动静分离原理

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

二.Nginx 负载均衡模式

1.轮询(默认)

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

2.加权轮询

weight值越大,被分配到的访问请求概率越高,主要用于后端服务器性能不均匀的情况。

3.least_conn 最小连接

优先将客户端请求调度到当前连接最少的服务器。

4.ip_hash

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

5.fair(第三方)

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

6.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定义路径

7.nginx七层反向代理配置

基于http、https、mail等七层应用协议的代理转发(根据用户访问请求的URL路径来转发请求),通常用于 动静分离 等应用场景

1)在http配置块中使用upstream定义后端服务器列表名称和节点参数
http {
    upstream 服务器池名称 {
        server IP1:PORT1 weight=1;
        server IP2:PORT2 weight=1;
        ......
    }


2)在server配置块中使用location匹配用户请求的动态页面的URL路径,使用 proxy_pass 基于协议代理转发
    server {
        ......
        location ~ .*\.jsp$ {
            proxy_pass http://服务器池名称;
            
            #用于为后端服务器获取真实的客户端地址
            proxy_set_header HOST $host;
            proxy_set_header X_Real_IP $remote_addr;
            proxy_set_header X_Forwarded_For $proxy_add_x_forwarded_for;
        }
    ......
    }
......
}

8.四层反向代理配置

基于 IP 和 端口 实现的代理转发(根据用户请求的IP和端口来转发请求),通常用于做 网关访问入口的负载均衡器 等应用场景

1)编译安装时需要添加 stream 四层代理模块  ./configure --with-stream

2)在 http 配置块同层级,一般在 http 配置块上面添加 stream 配置块,在 stream 配置块里使用upstream定义后端服务器列表名称和节点参数以及使用server配置块定义监听端口和转发配置
stream {
    upstream 服务器池名称 {
        server IP1:PORT1 weight=1;
        server IP2:PORT2 weight=1;
        ......
    }

    server {
        listen IP:PORT;
        proxy_pass 服务器池名称;
    }
}

http {....}

三.配置服务器

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/

添加system管理nginx服务

#添加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

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

3.配置Nginx动静分离

(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>

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

4.Nginx 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负载均衡如何实现会话保持?

(1)ip_hash 或 一致性hash算法                        基于客户端IP做hash缓存将请求发送给同一个后端节点服务器来实现会话保持,但是此方法容易导致负载失衡问题

(2)sticky_cookie_insert                             基于cookie来判断实现会话保持
    upstream backend {
    server ...... ;
    sticky_cookie_insert srv_id expires=浏览器中保持cookie的时间 domain=cookie的域名 path=cookie的路径;
    }
    
(3)后端应用服务器自身通过相关机制设置,使用缓存数据库为后端节点服务器做session同步复制实现会话保持
相关推荐
尢词8 小时前
SpringMVC
java·spring·java-ee·tomcat·maven
清风百草8 小时前
【04】【Maven项目热部署】将Maven项目热部署到远程tomcat服务器上
tomcat·maven项目热部署
JustCouvrir15 小时前
macOS|前端工程部署到Nginx服务器
服务器·前端·nginx
AlbertS16 小时前
使用 Let’s Encrypt 获取免费SSL证书
nginx·免费·centos7·ssl证书·let’s encrypt
航月16 小时前
FTP、ISCSI、CHRONY、DNS、NFS、DOCKER、MARIADB、NGINX、PHP、CA各服务开启方法
nginx·docker·mariadb
IT-民工2111021 小时前
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·负载均衡
雷神乐乐1 天前
IDEA构建JavaWeb项目,并通过Tomcat成功运行
服务器·tomcat·javaweb