Nginx+Tomcat负载均衡、动静分离集群
一.Nginx负载均衡实现原理
Nginx实现负载均衡是通过反向代理实现
1、 反向代理原理
2、反向代理的概念
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
反向代理是为服务端服务的,反向代理可以帮助服务器接收来自客户端的请求,帮助服务器做请求转发,负载均衡等。
反向代理对服务端是透明的,对我们是非透明的,即我们并不知道自己访问的是代理服务器,而服务器知道反向代理在为他服务。
3、反向代理的优势
反向代理的优势:
- 隐藏真实服务器;
- 负载均衡便于横向扩充后端动态服务;
- 动静分离,提升系统健壮性;
4、Nginx四层反向代理和七层反向代理
四层反向代理:是基于IP+PORT(TCP/UDP端口)转发
七层反向代理:基于http,https,mail代理转发
5、Nginx
实现负载均衡的策略:
- 轮询策略:默认情况下采用的策略,将所有客户端请求轮询分配给服务端。这种策略是可以正常工作的,但是如果其中某一台服务器压力太大,出现延迟,会影响所有分配在这台服务器下的用户。
- 最小连接数策略:将请求优先分配给压力较小的服务器,它可以平衡每个队列的长度,并避免向压力大的服务器添加更多的请求。
- 最快响应时间策略:优先分配给响应时间最短的服务器。
- 客户端
ip
绑定策略:来自同一个ip
的请求永远只分配一台服务器,有效解决了动态网页存在的session
共享问题。
二、Nginx动静分离实现原理
1、动静分离的概念
动静分离是指在 web
服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提示整个服务的访问性和可维护性。
2、动静分离的原理
服务端接收来自客户端的请求中。既有静态资源也有动态资源,静态资源由Nginx提供服务,动态资源Nginx转发至后端
3、Nginx 静态处理优势
• Nginx处理静态页面的效率远高于Tomcat的处理能力
• 若Tomcat的请求量为1000次,则Nginx的请求量为6000次
• Tomcat每秒的吞吐量为0.6M,Nginx的每秒吞吐量为3.6M
• Nginx处理静态资源的能力是Tomcat处理的6倍
三、Nginx负载均衡模式(5种)
1、rr负载均衡模式
每个请求按时间顺序逐一分配到不同的后端服务器,如果超过了最大失败次数后(max_fails,默认1),在失效时间内(fail_timeout,默认10秒),该节点失效权重变为0,超过失效时间后,则恢复正常,或者全部节点都为down后, 那么将所有节点都恢复为有效继续探测,一般来说rr可以根据权重来进行均匀分配。
2、least_conn最少连接
优先将客 户端请求调度到当前连接最少的服务器。
3、ip_hash负载均衡模式
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器, 可以解决session(会话状态)的问题,但是ip_hash会造成负载不均,有的服务请求接受多,有的服务请求接受少,所以不建议采用ip_hash模式
补充:session的概念
session共享问题可用后端服务的session共享代替nginx的ip_hash。ip_hash无法作用于四层反向代理,配置需要将其他模式删除例如weight删掉然后直接在加上
注释:
Session又称为会话状态,是Web系统中最常用的状态,用于维护和当前浏览器实例相关的一些信息。我们控制用户去权限中经常用到Session来存储用户状态
session其实分为客户端Session和服务器端Session。
当用户首次与Web服务器建立连接的时候,服务器会给用户分发一个 SessionID作为标识。SessionID是一个由24个字符组成的随机字符串。用户每次提交页面,浏览器都会把这个SessionID包含在 HTTP头中提交给Web服务器,这样Web服务器就能区分当前请求页面的是哪一个客户端。这个SessionID就是保存在客户端的,属于客户端Session。
其实客户端Session默认是以cookie的形式来存储的,所以当用户禁用了cookie的话,服务器端就得不到SessionID。这时我们可以使用url的方式来存储客户端Session。也就是将SessionID直接写在了url中,当然这种方法不常用。
Session共享:指在一个浏览器对应多个Web服务时,服务端的Session数据需要共享。例如单点登录、Web服务器集群等场景都需要用到、多子服务。
4、fair(第三方)负载均衡模式
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
5、url_hash(第三方)负载均衡模式
和ip hash算法类似,是对每个请求按url的hash结果分配,使每个URL定向到同一个后端服务器, 但是也会造成分配不均的问题, 这种模式后端服务器为缓存时比较好。
四、Nginx+Tomcat负载均衡、动静分离的操作步骤
1、准备三台服务器,Nginx作为负载均衡器,Tomcat作为应用服务器
Nginx 服务器:192.168.229.60:80
Tomcat服务器1:192.168.229.70:80
Tomcat服务器2:192.168.229.90:8080 192.168.229.90:8081
2、部署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 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加密功能 ---------------------------------------------------------------------------------------------------------- ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-file-aio --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module make && make install ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ 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
3、部署2台Tomcat 应用服务器
systemctl stop firewalld setenforce 0 tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/ vim /etc/profile.d/java.sh 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:$PATH source /etc/profile.d/java.sh tar zxvf apache-tomcat-8.5.16.tar.gz mv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat /usr/local/tomcat/bin/shutdown.sh /usr/local/tomcat/bin/startup.sh netstat -ntap | grep 8080
4、动静分离配置
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>
vim /usr/local/tomcat/conf/server.xml #由于主机名 name 配置都为 localhost,需要删除前面的 HOST 配置 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true"> </Context> </Host> /usr/local/tomcat/bin/shutdown.sh /usr/local/tomcat/bin/startup.sh
Tomcat2 server 配置(多实例)
mkdir /usr/local/tomcat/tomcat1/webapps/test /usr/local/tomcat/tomcat2/webapps/test vim /usr/local/tomcat/tomcat1/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/tomcat1/conf/server.xml #删除前面的 HOST 配置 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/tomcat/tomcat1/webapps/test" path="" reloadable="true" /> </Host> /usr/local/tomcat/tomcat1/bin/shutdown.sh /usr/local/tomcat/tomcat1/bin/startup.sh vim /usr/local/tomcat/tomcat2/webapps/test/index.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>JSP test3 page</title> #指定为 test3 页面 </head> <body> <% out.println("动态页面 3,http://www.test3.com");%> </body> </html> vim /usr/local/tomcat/tomcat2/conf/server.xml #删除前面的 HOST 配置 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/tomcat/tomcat2/webapps/test" path="" reloadable="true" /> </Host> /usr/local/tomcat/tomcat2/bin/shutdown.sh /usr/local/tomcat/tomcat2/bin/startup.sh
Nginx server 配置——七层转发配置
#准备静态页面和静态图片 echo '<html><body><h1>这是静态页面</h1></body></html>' > /usr/local/nginx/html/index.html mkdir /usr/local/nginx/html/img cp /root/game.jpg /usr/local/nginx/html/img vim /usr/local/nginx/conf/nginx.conf ...... http { ...... #gzip on; #配置负载均衡的服务器列表,weight参数表示权重,权重越高,被分配到的概率越大 upstream tomcat_server { server 192.168.116.70:8080 weight=1; server 192.168.116.120:8080 weight=1; server 192.168.116.120: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; } ...... } ...... }
5、测试效果
测试静态页面效果
浏览器访问 http://192.168.229.60/
浏览器访问 http://192.168.229.60/meme.jpg
测试负载均衡效果,不断刷新浏览器测试
浏览器访问 http://192.168.229.60/index.jsp
五、实例操作:Nginx+Tomcat负载均衡、动静分离
1、准备好Nginx服务器(192.168.229.60)
2、准备好tomcat服务器1(192.168.229.70:8080)
3、准备好Tomcat服务器2(两个实例):192.168.229.90:8080 192.168.229.90:8081——参照此篇文章:Tomcat 多实例部署
4、动静分离Tomcat1 server 配置
4.1 配置Tomcat1的动态网页显示内容
[root@192 opt]# mkdir /usr/local/tomcat/webapps/test [root@192 opt]# cd /usr/local/tomcat/webapps/ [root@192 webapps]# ls docs examples host-manager manager ROOT test [root@192 webapps]# cd test/ [root@192 test]# ls
[root@192 ~]# 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,tomcat1服务器");%> </body> </html>
4.2 添加新的host内容
[root@192 conf]# pwd /usr/local/tomcat/conf [root@192 conf]# ls Catalina catalina.properties jaspic-providers.xml logging.properties tomcat-users.xml web.xml catalina.policy context.xml jaspic-providers.xsd server.xml tomcat-users.xsd [root@192 conf]# cp server.xml{,.bak} [root@192 conf]# ls Catalina catalina.properties jaspic-providers.xml logging.properties server.xml.bak tomcat-users.xsd catalina.policy context.xml jaspic-providers.xsd server.xml tomcat-users.xml web.xml [root@192 conf]# vim server.xml
4.3 重启服务
[root@192 conf]# /usr/local/tomcat/bin/shutdown.sh Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr/java/jdk1.8.0_201-amd64 Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar [root@192 conf]# /usr/local/tomcat/bin/startup.sh Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr/java/jdk1.8.0_201-amd64 Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Tomcat started. [root@192 conf]# netstat -natp | grep 8080 tcp6 0 0 :::8080 :::* LISTEN 7764/java tcp6 0 0 ::1:52612 ::1:8080 TIME_WAIT -
5、Tomcat2 server 配置(实例1)
5.1 创建Tomcat实例1的网页测试目录test和测试网页文件
[root@192 ~]# mkdir /usr/local/tomcat/tomcat1/webapps/test
[root@192 test]# vim /usr/local/tomcat/tomcat1/webapps/test/index.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>JSP test2 page</title> </head> <body> <% out.println("动态页面2,tomcat2服务器中的实例1");%> </body> </html>
5.2 Tomcat实例1主配置删除前面的 HOST 配置,添加新的HOST配置
[root@192 conf]# ls Catalina catalina.properties jaspic-providers.xml logging.properties tomcat-users.xml web.xml catalina.policy context.xml jaspic-providers.xsd server.xml tomcat-users.xsd [root@192 conf]# cp server.xml{,.bak} [root@192 conf]# vim server.xml <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/tomcat/tomcat1/webapps/test" path="" reloadable="true"> </Context> </Host>
5.3 重启服务
[root@192 ~]# /usr/local/tomcat/tomcat1/bin/shutdown.sh Using CATALINA_BASE: /usr/local/tomcat/tomcat1 Using CATALINA_HOME: /usr/local/tomcat/tomcat1 Using CATALINA_TMPDIR: /usr/local/tomcat/tomcat1/temp Using JRE_HOME: /usr/java/jdk1.8.0_201-amd64 Using CLASSPATH: /usr/local/tomcat/tomcat1/bin/bootstrap.jar:/usr/local/tomcat/tomcat1/bin/tomcat-juli.jar [root@192 ~]# /usr/local/tomcat/tomcat1/bin/startup.sh Using CATALINA_BASE: /usr/local/tomcat/tomcat1 Using CATALINA_HOME: /usr/local/tomcat/tomcat1 Using CATALINA_TMPDIR: /usr/local/tomcat/tomcat1/temp Using JRE_HOME: /usr/java/jdk1.8.0_201-amd64 Using CLASSPATH: /usr/local/tomcat/tomcat1/bin/bootstrap.jar:/usr/local/tomcat/tomcat1/bin/tomcat-juli.jar Tomcat started. [root@192 ~]# netstat -natp | grep java tcp6 0 0 :::8080 :::* LISTEN 5096/java tcp6 0 0 :::8081 :::* LISTEN 3757/java tcp6 0 0 127.0.0.1:8005 :::* LISTEN 5096/java tcp6 0 0 127.0.0.1:8006 :::* LISTEN 3757/java tcp6 0 0 :::8009 :::* LISTEN 5096/java tcp6 0 0 :::8010 :::* LISTEN 3757/java
6、Tomcat2 server 配置(实例2)
6.1 创建Tomcat实例2的网页测试目录test和测试网页文件
[root@192 ~]# mkdir /usr/local/tomcat/tomcat2/webapps/test
[root@192 test]# vim /usr/local/tomcat/tomcat2/webapps/test/index.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>JSP test3 page</title> </head> <body> <% out.println("动态页面3,tomcat2服务器中的实例2");%> </body> </html>
6.2 Tomcat实例2主配置删除前面的 HOST 配置,添加新的HOST配置
6.3 重启服务
7、Nginx server 配置(192.168.229.60)
7.1 准备网页显示相关内容
[root@cm ~]# vim /usr/local/nginx/html/index.html [root@cm ~]# cat /usr/local/nginx/html/index.html <html><body><h1>这是静态页面!</h1></body></html> [root@cm ~]# mkdir /usr/local/nginx/html/img [root@cm ~]# cd /usr/local/nginx/html/img/ [root@cm img]# rz -E rz waiting to receive. [root@cm img]# ls meme.jpg
7.2 修改主配置文件——七层转发配置
7.3 重启服务
[root@cm ~]# 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 [root@cm ~]# systemctl restart nginx.service
8、使用win10客户端在浏览器中进行测试,动态页面测试进行不断刷新即可
测试静态页面效果
浏览器访问 http://192.168.229.60/
浏览器访问 http://192.168.229.60/meme.jpg
测试负载均衡效果,不断刷新浏览器测试
浏览器访问 http://192.168.229.60/index.jsp
8.1 测试静态页面效果
8.2 测试负载均衡效果,不断刷新浏览器测试
六、Nginx四层代理配置
1、nginx 从1.9.0版本开始支持四层代理,但做四层代理时 编译需要添加 --with-stream模块
./configure
........
--with-stream #需要安装该模块
1.1 查看当前模块
[root@cm ~]# nginx -V nginx version: nginx/1.12.2 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-file-aio --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module
1.2 在已有的nginx上面添加该模块--with-stream
[root@cm nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-file-aio --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-stream [root@cm nginx-1.12.2]# make [root@cm nginx-1.12.2]# /usr/local/nginx/sbin/nginx -s stop [root@cm nginx-1.12.2]# cp objs/nginx /usr/local/nginx/sbin/nginx cp:是否覆盖"/usr/local/nginx/sbin/nginx"? no [root@cm nginx-1.12.2]# cp /usr/local/nginx/sbin/nginx{,.bak} [root@cm nginx-1.12.2]# cp objs/nginx /usr/local/nginx/sbin/nginx cp:是否覆盖"/usr/local/nginx/sbin/nginx"? yes [root@cm nginx-1.12.2]# /usr/local/nginx/sbin/nginx [root@cm nginx-1.12.2]# netstat -natp | grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 8858/nginx: master [root@cm nginx-1.12.2]# nginx -V nginx version: nginx/1.12.2 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-file-aio --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-stream
2、nginx四层代理配置
和http同等级:所以一般只在http上面一段设置, stream { upstream appserver{ server 192.168.229.70:8080 weight=1; server 192.168.229.90:8080 weight=1; server 192.168.229.90:8081 weight=1; } server { listen 8080; proxy_pass appserver; } } http { ......
2.1 修改配置文件进行四层代理配置
2.2 重启服务
3 浏览器访问测试
基于端口访问,但是会有60s左右的缓存时间才会实现跳转到别的tomcat服务器
输入网址:http://192.168.229.60
输入网址:http://192.168.229.60:8080