nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)

一:实现访问动态页面

静态资源:指存储在硬盘内的数据,固定的数据,不需要计算的数据。

  • 如:图片、字体、js文件、css文件等等。在用户访问静态资源时,服务器会直接将这些资源返回到用户的计算机内。

动态资源:指需要服务器根据用户的操作所返回的数据,以及存储在数据库的数据,经过一系列逻辑计算后返回的数据。

  • 如:请求明天的天气信息数据、请求查看账户余额。

请求动态数据与请求静态资源的分离的必要性:

  • Tomcat应用服务器是用来处理Servlet容器和JSP的,虽然它也可以处理HTML等等一系列静态资源,但是效率不如Nginx;而且tomcat对Servlet容器和JSP的运算已经有很大压力了,如果不分离会导致大量的性能浪费。说到底,在应用服务方面,要遵循一条原则——一个服务只做一件事。要做动态请求就专做动态请求,要做静态请求就专做静态请求,这样才能提高性能。

实验原理:

我们要做的,就是当用户访问静态资源时,让Nginx将静态资源返回给用户(以前实验做过,就不多做叙述);当用户访问动态资源时,将访问转到Tomcat应用服务器上,Tomcat将数据返回给Nginx,Nginx再返回给用户。

第一步:安装jdk和tomcat将其放至/usr/local目录下并创建软连接

[root@hang1 sbin]# cd /mnt
[root@hang1 mnt]# ls
[root@hang1 mnt]# tar zxf jdk-7u79-linux-x64.tar.gz  -C /usr/local
[root@hang1 mnt]# tar zxf apache-tomcat-7.0.37.tar.gz  -C /usr/local

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第1张图片

[root@hang1 mnt]# cd /usr/local
[root@hang1 local]# ll
[root@hang1 local]# ln -s apache-tomcat-7.0.37   tomcat

在这里插入图片描述
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第2张图片

第二步:.配置java的环境变量并使其生效并打开tomcat

[root@hang1 ~]# cd /usr/local
[root@hang1 local]# vim /etc/profile
编辑文件内容如下所示:
export JAVA_HOME=/usr/local/jdk1.7.0_79
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export  PATH=$PATH:$JAVA_HOME/bin
[root@hang1 local]# source /etc/profile

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第3张图片

[root@hang1 local]# cd tomcat/
[root@hang1 bin]# ls
[root@hang1 tomcat]# cd bin/
[root@hang1 bin]# ls
[root@hang1 bin]# ./startup.sh        #启动tomcat

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第4张图片

查看端口,默认开启8080端口:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第5张图片

此时去浏览器访问

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第6张图片
此时访问不到,因为openresty开启的80端口
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第7张图片
第三步:编辑openresty的配置文件并重启服务

注意:这个实验的配置文件是在上一个实验的配置文件的基础上修改的

[root@hang1 conf]# cd /usr/local/openresty/nginx/
[root@hang1 nginx]# cd conf/
[root@hang1 conf]# ls
[root@hang1 conf]# vim nginx.conf
 72         location ~ \.jsp$ {
 73             proxy_pass   http://127.0.0.1:8080;
 74         }

[root@hang1 conf]# ../sbin/nginx -s reload

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第8张图片

在这里插入图片描述

在这里插入图片描述

此时再去访问就可以访问到:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第9张图片

但这个能访问到动态的jsp效果不太明显,所以我们重新编辑测试页

第四步:重次编辑测试页

[root@hang1 ~]# vim test.jsp
[root@hang1 ~]# cat test.jsp
the time is:<%=new java.util.Date() %>
[root@hang1 ~]# mv test.jsp /usr/local/tomcat/webapps/ROOT/       #将发布文件移动到发布目录下
[root@hang1 ~]# cd /usr/local/tomcat/webapps/ROOT/
[root@hang1 ROOT]# ls

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第10张图片
当我们访问的时候,时间会一直变化,实现了访问动态页面

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第11张图片

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第12张图片
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第13张图片

二:nginx+tomcat实现负载均衡

负载均衡即是代理服务器将接收的请求均衡的分发到各服务器中。

  • 负载均衡的优势在访问量少或并发小的时候可能并不明显,且不说淘宝双11、铁道部抢票这种级别的访问量、高并发,就是一般网站的抢购活动时,也会给服务器造成很大压力,可能会造成服务器崩溃。而负载均衡可以很明显的减少甚至消除这种情况的出现,

实现原理:

首先我们再开启一个tomcat服务器,这里区分一下就叫tomcat2吧,原先的叫tomcat1。将tomcat1上的项目,拷贝到tomcat2上,稍微修改下页面上的文字以便等下区分我们的请求被分发到了哪个tomcat上。

第一步:重新开一台虚拟机,将1中的jdk和tomcat发送到2上,并配置2的实验环境

在这里插入图片描述
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第14张图片

[root@hang1 local]# scp -r apache-tomcat-7.0.37  jdk1.7.0_79  hang2:/usr/local/

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第15张图片

为了放心,查看:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第16张图片

依旧和1上面一样的操作:配置环境变量,创建软连接

[root@hang2 local]# vim /etc/profile
[root@hang2 local]# tail -n 3 /etc/profile
export JAVA_HOME=/usr/local/jdk1.7.0_79
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export  PATH=$PATH:$JAVA_HOME/bin

[root@hang2 local]# ln -s apache-tomcat-7.0.37   tomcat
[root@hang2 local]# source /etc/profile

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第17张图片

在这里插入图片描述
在这里插入图片描述

第二步:在1中编辑openresty中配置文件中的内容并检测是否有错

[root@hang1 local]# cd /usr/local/openresty/nginx/conf/
[root@hang1 conf]# vim nginx.conf

17 http {
 18 upstream tomcat{
 19         server 172.25.11.1:8080;        #后端服务器1
 20         server  172.25.11.2:8080;       #后端服务器2
 21 }
 22     include       mime.types;
 23     default_type  application/octet-stream;

 73         location ~ \.jsp$ {
 74             proxy_pass   http://tomcat;          #使其访问tomcat
 75         }

在这里插入图片描述
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第18张图片

在这里插入图片描述

注意:这一块为了实验效果,将不需要的代码条注释掉:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第19张图片
你可以在这一块之后就重启openrest的nginx服务,也可以后面重启,我是后面重启的~~~~

第三步:编辑测试页

将原本的测试页删除:

[root@hang1 local]# cd /usr/local/tomcat/webapps/ROOT/
[root@hang1 ROOT]# pwd
/usr/local/tomcat/webapps/ROOT
[root@hang1 ROOT]# ls
[root@hang1 ROOT]# rm -fr test.jsp 

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第20张图片

从真机上传一个测试页:

[kiosk@foundation11 ~]$ scp test.jsp [email protected]:/usr/local/tomcat/webapps/ROOT/

在这里插入图片描述

再去查看:

在这里插入图片描述
将这个测试页发送给2

root@hang1 ROOT]# scp test.jsp [email protected]:/usr/local/tomcat/webapps/ROOT/

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第21张图片

在2上面查看:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第22张图片

第四步:重启tomcat(tomcat的重启只能先关闭先开启)

[root@hang1 ROOT]# cd ..
[root@hang1 webapps]# cd ..
[root@hang1 tomcat]# cd bin/
[root@hang1 bin]# ./shutdown.sh 
[root@hang1 bin]# ./startup.sh 
[root@hang1 bin]# netstat -tnlp

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第23张图片
查看端口:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第24张图片

在2上面也重启:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第25张图片

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第26张图片

查看端口:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第27张图片
第五步:重启openresty的nginx服务,再测试

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第28张图片

在浏览器访问测试页:
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第29张图片
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第30张图片

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第31张图片

注意,在企业里这两个页面应该是一样的,用户根本不知道你访问的那个服务器,这里只是为了实验效果,你要是觉得这个测试页不够明显,你也可以使用以下代码做的测试页:

hang1上面:

hang1  the time is:<%=new java.util.Date() %>

hang2上面:

hang2  the time is:<%=new java.util.Date() %>

会出现类似下面的结果:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第32张图片

在上面的实验过程中,我们虽然看见了实现了负载均衡,但是1上面的数据信息会存储到2上面,2上面的数据信息会存储到2上面,而且新的数据就会覆盖旧的数据内容,这样会造成数据的丢失。为了解决这个问题,我们需要使用sticky模块来实现负载均衡中的会话保持。

三.使用nginx中的第三方sticky模块实现负载均衡中的会话保持

什么是会话保持:

会话保持是负载均衡最常见的问题之一,也是一个相对比较复杂的问题。

会话保持有时候又叫做粘滞会话(Sticky Sessions)。

在介绍会话保持技术之前,我们必须先花点时间弄清楚一些概念:什么是连接(Connection)、什么是会话(Session),以及这二者之间的区别。需要特别强调的是,如果我们仅仅是谈论负载均衡,会话和连接往往具有相同的含义。

从简单的角度来看,

如果用户需要登录,那么就可以简单的理解为会话;

如果不需要登录,那么就是连接。

  • 实际上,会话保持机制与负载均衡的基本功能是完全矛盾的。负载均衡希望将来自客户端的连接、请求均衡的转发至后端的多台服务器,以避免单台服务器负载过高;而会话保持机制却要求将某些请求转发至同一台服务器进行处理。因此,在实际的部署环境中,我们要根据应用环境的特点,选择适当的会话保持机制。

原始负载均衡的基本原理:

  • 对于同一个连接中的数据包,负载均衡会将其进行NAT转换后,转发至后端固定的服务器进行处理,这是负载均衡最基本、最原始的功能。负载均衡系统内部会专门有一张表来记录这些连接的状况,包括:[源IP:端口]、[目的IP:端口]、[服务器IP:端口]、空闲超时时间(Idle
    Timeout)等等。

由于负载均衡内部记录连接状态的这张表需要消耗系统的内存资源,因此,这张表不可能无限大,所有厂家都会有一定的限制。这张表的大小一般称之为最大并发连接数,也就是系统同时能够容纳的连接数量。考虑到建立这些连接的客户端或服务器会发生一些异常状况,导致这些连接不能被正常终结掉,因此,负载均衡的当前连接状态表项中,设计了一个空闲超时时间的参数。这个参数定义为,当该连接在一定时间内无流量通过时,负载均衡会自动删除该连接条目,释放系统资源。

看了这段文字之后,应该就能够很好的理解为什么负载均衡的硬件设备的发展速度,无法和软件的发展相比较。因为这个硬件的发展速度,比不上服务器的发展速度….

有了会话之后,使用原始的负载均衡就会有问题,常见的异常场景包括:

  • 客户端输入了正确的用户名和口令,但却反复跳到登录页面;

  • 用户输入了正确的验证码,但是总提示验证码错误;

  • 客户端放入购物篮的物品丢失

因此,会话保持机制的意义就在于,确保将来自相同客户端的请求,转发至后端相同的服务器进行处理。换句话说,就是将客户端与服务器之间建立的多个连接,都发送到相同的服务器进行处理。如果在客户端和服务器之间部署了负载均衡设备,很有可能,这多个连接会被转发至不同的服务器进行处理。如果服务器之间没有会话信息的同步机制,会导致其他服务器无法识别用户身份,造成用户在和应用系统发生交互时出现异常。

详情请点击

大家都知道nginx抗并发能力强,又可以做负载均衡,而且使用nginx对我们目前的网站架构不会有大的变动,所以首选方案是nginx。但问题来了,nginx在会话保持这方面比较弱,用ip_hash做会话保持有很大的缺陷,它是通过客户端ip来实现,根据访问ip的hash结果分配请求到后端的app服务器,负载不会很均匀。所以我们打算使用nginx-sticky-module这个第三方模块,它可以基于cookie实现会话保持。

nginx中的的ip_hash机制:

  • Nginx中的ip_hash技术能够将某个ip 的请求定向到同一台后端web机器中,这样一来这个ip 下的客户端和某个后端
    web机器就能建立起稳固的session.
  • ip_hash机制能够让某一客户机在相当长的一段时间内只访问固定的后端的某台真实的web服务器,这样会话就会得以保持,在网站页面进行login的时候就不会在后面的web服务器之间跳来跳去了,也不会出现登录一次的网站又提醒重新登录的情况.

Ip_hash机制缺陷:

  • (1).nginx不是最前端的服务器:ip_hash要求nginx一定是最前端的服务器,否则nginx得不到正确ip,就不能根据ip作hash. Eg: 使用的是squid为最前端.那么nginx取ip时只能得到squid的服务器ip地址,用这个地址来作分流肯定是错乱的

  • (2).nginx的后端还有其它负载均衡 :假如nginx后端还有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台session应用服务器上,

sticky模块与Ip_hash都是与负载均衡算法相关,但又有差别,差别是:

1.ip hash,根据客户端的IP,将请求分配到不同的服务器上

2.sticky,根据服务器给客户端的cookie,客户端再次请求时会带上此cookie,nginx会把有此cookie的请求转发到颁发cookie的服务器上

注意:在一个局域网内有3台电脑,他们有3个内网IP,但是他们发起请求时,却只有一个外网IP,是电信运营商分配在他们连接那个路由器上的,如果使用 ip_hash 方式,则Nginx会将请求分配到不同上游服务器,如果使用 sticky 模块,则会把请求分配到办法cookie的服务器上,实现:内网nat用户的均衡。这是ip_hash无法做到的

Sticky工作原理:

Sticky是基于cookie的一种负载均衡解决方案,通过分发和识别cookie,使来自同一个客户端的请求落在同一台服务器上,默认cookie标识名为route :

1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
2.后端服务器处理完请求,将响应数据返回给nginx。
3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值
4.客户端接收请求,并保存带route的cookie。
5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。

实验如下:

第一步:重新解压nginx和nginx的sticky安装包并编译三部曲

在物理机将包传到要做实验的虚拟机里:

[root@foundation11 ~]# scp -r nginx-1.10.1.tar.gz   nginx-sticky-module-ng.tar.gz  [email protected]:/mnt

在这里插入图片描述

[root@hang1 bin]# cd /mnt
[root@hang1 mnt]# ls
[root@hang1 mnt]# tar zxf nginx-1.10.1.tar.gz
[root@hang1 mnt]# tar zxf nginx-sticky-module-ng.tar.gz
[root@hang1 mnt]# ls
[root@hang1 mnt]# /usr/local/lnmp/nginx/sbin/nginx -V
[root@hang1 mnt]# cd nginx-1.10.1

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第33张图片

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第34张图片
在这一步去注释掉debug日志,显示不显示nginx的版本号看你自己,不影响实验,但是记得在企业中不能显示nginx的版本号噢,这里我就不做演示拉~

另外如果做过openresty的实验,记得先把openresty的nginx关掉,否则会占用端口,我就是因为没有关掉,后面还做了kill的操作…

cd /usr/local/openresty/nginx/sbin/    
./nginx -s stop

重新编译,因为我们要将sticky模块加入进去:

[root@hang1 nginx-1.10.1]# ./configure  --prefix=/usr/local/lnmp/nginx  \
--with-http_ssl_module  \
--with-http_stub_status_module  \
--with-threads --with-file-aio  \
--user=nginx --group=nginx  \
--add-module=/mnt/nginx-sticky-module-ng

[root@hang1 nginx-1.10.1]# make && make install

在这里插入图片描述
预编译完成的界面如下所示:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第35张图片
查看模块文件,看是否有sticky的模块
在这里插入图片描述
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第36张图片
编译
在这里插入图片描述

第二步:编写新的nginx配置文件(把原来openresty下的nginx配置文件直接复制过来即可)

[root@hang1 nginx]# cp /usr/local/openresty/nginx/conf/nginx.conf  conf/
[root@hang1 nginx]# cd conf/
[root@hang1 conf]# vim nginx.conf
 17 http {
 18 upstream tomcat{
 19         sticky;
 20         server 172.25.11.1:8080;
 21         server  172.25.11.2:8080;
 22 }
 23     include       mime.types;
 24     default_type  application/octet-stream;
[root@hang1 conf]# ../sbin/nginx

在这里插入图片描述
在这里插入图片描述

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第37张图片

不用的代码可以注释掉:
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第38张图片

第三步:重启服务

[root@hang1 conf]# ../sbin/nginx

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第39张图片

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第40张图片

在去查看80端口:
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第41张图片

第四步:测试

清除浏览器缓存:

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第42张图片

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第43张图片
但是此时还有一个问题,就是我们关闭1上面的tomcat,却发现1上面的数据没有同步到2上面

nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第44张图片
nginx+tomcat——实现访问动态页面以及负载均衡(内含sticky使会话保持)_第45张图片

关于这个问题我们下一篇博客见~~~~~~~

你可能感兴趣的:(linux运维)