第二讲—Nginx,Tomcat集群,Session通过Redis共享

这章要演示的东西比较多,Sad!一步一步来,不要急。

 

一、使用Nginx代理,访问我们两个Tomcat的应用,每个Tomcat都有自己的Session。通过Nginx做负载均衡,访问Tomcat应用的搭建过程,请参照:第一讲—Nginx入门实战

二、为了区别负载均衡后,我们需要新建一个Web应用,写一个Servlet,打印当前应用名称,时间,和SessionID。为了区分来自不同的应用,Servlet我们要区分出来,打两次war包

第一个打包的Servlet的打印信息如下,打成war包,放到Tomcat1下

out.println("Tomcat_One   " + new SimpleDateFormat("yyyy-MM-dd mm:HH:ss").format(new Date()) + "   sessionId----->" + session.getId());

第二个打包的Servlet的打印信息为:,打成war包,放到Tomcat2下

out.println("Tomcat_Two   " + new SimpleDateFormat("yyyy-MM-dd mm:HH:ss").format(new Date()) + "   sessionId----->" + session.getId());
package com.minutch;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
@WebServlet( "/GetInfoServlet" )
public class GetInfoServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;
     
     public GetInfoServlet() {
         super();
     }
 
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         HttpSession session = request.getSession();
         PrintWriter out = response.getWriter();
         out.println( "Tomcat_One   " + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ). format (new Date()) + "   sessionId----->" + session.getId());
     }
 
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     }
}

三、我们不改变Tomcat 的任何配置,也不持久化Session,也不接入Redis,先看看效果(注意:为了达到轮流访问两个Tomcat的应用,Nginx不配置任何分发策略,默认就是轮询方式)

       3.1 效果:

               访问Servlet第一次,结果如下:Tomcat_One 2015-04-02 19:19:03 sessionId----->1CD5F28AE679A83B3B089BB672EE4BE6

               访问Servlet第二次,结果如下:Tomcat_Two 2015-04-02 19:19:05 sessionId----->2FDSF25ACF39A85F6F3LICB653SD3CF7

               访问Servlet第三次,结果如下:Tomcat_One 2015-04-02 19:19:10 sessionId----->D78714263D498E4316E0F7199BC39896S

               访问Servlet第四次,结果如下:Tomcat_Two 2015-04-02 19:19:18 sessionId----->634AE2CC6E6AEC18F154B9A2BE2863F2

 

      3.2 分析

              通过结果,我们可以发现,Nginx会轮流把请求发到两个Tomcat上,但是我明明在同一个浏览器,同一个页面发的请求,为什么SessionId每次都在变化呢,看下面的解释?

              第一次请求,访问Tomcat1,Tomcat1后台生成一个Session,这时,返回前端一个SessionId,假设为SessionIDA。

              第二次请求,访问Tomcat2,这个请求会把SessionIDA传到Tomcat2的后台,寻找是否存在SessionID为SessionIDA的Session,显然是找不到的,于是Tomcat2生成一个新的Session,并把SessionID返回前端,假设SessionID为SessionIDB。

              第三次请求,访问Tomcat1,这次请求会把SessionIDB传到Tomcat1的后台,寻找是否存在SessionID为SessionIDB的Session,此时Tomcat1只有SessionIDA的Session,所以也不能找到,于是生成一个新的Session,SessionID为SessionIDC,返回到前端,然后开始循环这个操作,这样就可以解释上面的结果了。

 

四、我们仍然不改变Tomcat的任何配置,也不持久化Session,也不接入Redis,但是Nginx稍微有点变化,我们在Nginx.conf的配置文件加了一点东西,具体往下看

upstream saint {
    server   127.0.0.1:9000;
    server   127.0.0.1:9001;
 
    ip_hash;  #加了这个配置,根据IP来分发请求,也就是相同的IP会发到同一个Tomcat上,我们来看看效果
  }

      

        用同一个浏览器,多次访问Servlet

        4.1 效果

                第一次请求:Tomcat_Two 2015-04-02 19:25:10 sessionId----->21C1E68E0A142A205E8DCD87C2D13188

                第二次请求:Tomcat_Two 2015-04-02 19:25:15 sessionId----->21C1E68E0A142A205E8DCD87C2D13188

                第三次请求:Tomcat_Two 2015-04-02 19:25:19 sessionId----->21C1E68E0A142A205E8DCD87C2D13188

        4.2 分析

                都是一样的,因为相同的IP发到同一台Tomcat2上,后台产生的SessionId返回到前端,前端在次访问时,通过这个SessionID是能找到Session的,所以不会创建新的Session。

 

五、来点刺激的,Tomcat的Session共享,把Session迁移到Redis中,然后我们把Nginx的那个ip_hash配置去掉。

      Tomcat的Session配置在第一讲后半段提过,这里再写一次。

      5.1 启动Redis服务器,使用默认端口

src /redis-server

      5.2 配置Tomcat持久化Session到Redis需要的jar (版本不对可能会报classNotFoundException,我开始用commons-pool-2.3.jar,jredis-1.0rc.jar,都不行)

       commons-pool-1.6.jar,

       jedis-2.1.0.jar

       tomcat-redis-session-manager-1.2-tomcat-7-java-7.jar

       将上面三个jar放到tomcat1,和tomcat2的lib目录下

       5.3 配置Tomcat'的content.xml文件,详情如下

 

< Context >
     <!-- Default set of monitored resources -->
     < WatchedResource >WEB-INF/web.xml</ WatchedResource >
     <!-- Uncomment this to disable session persistence across Tomcat restarts -->
     <!--
     <Manager pathname="" />
     -->
 
     <!--  Session持久化到文件的配置
     <Manager className="org.apache.catalina.session.PersistentManager">
         debug=0
         saveOnRestart="true"
         maxActiveSession="-1"
         minIdleSwap="-1"
         maxIdleSwap="-1"
         maxIdleBackup="1"
     <Store className="org.apache.catalina.session.FileStore"
            directory="/Users/Minutch/tomcatSession"
            />
     </Manager>
     -->
 
     < Valve className = "com.radiadesign.catalina.session.RedisSessionHandlerValve" />
     <!--Redis配置-->
     < Manager className = "com.radiadesign.catalina.session.RedisSessionManager"
                    host = "localhost"
                    port = "6379"
                    database = "0"
                    maxInactiveInterval = "10"
     />
 
     <!-- Uncomment this to enable Comet connection tacking (provides events
          on session expiration as well as webapp lifecycle) -->
     <!--
     <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
     -->
</ Context >

 

            5.4 配置Nginx.conf ,去掉ip_hash这个配置项,比较一下我们的变化,和第一次试验的时候相比,我们仅仅是增加了持久化Session到Redis的配置,那结果会怎么样呢,请往下看。

           效果:

           第一次请求结果:Tomcat_One 2015-04-02 19:32:30 sessionId----->D78714263D498E4316E0F7199BC39896

            第二次请求结果:Tomcat_Two 2015-04-02 19:33:10 sessionId----->D78714263D498E4316E0F7199BC39896

            第三次请求结果:Tomcat_One 2015-04-02 19:33:34 sessionId----->D78714263D498E4316E0F7199BC39896

            第四次请求结果:Tomcat_Two 2015-04-02 19:33:47 sessionId----->D78714263D498E4316E0F7199BC39896

            第五次请求结果:Tomcat_One 2015-04-02 19:34:08 sessionId----->D78714263D498E4316E0F7199BC39896

            

             分析:一开始叫我分析这个结果,其实我是拒绝的,因为如果我说的这个结果是假的,会在后期给我加特效,看官们自己看完学完发现不是这样的,那我就是在作假。所以我把所有流程走了一遍,做完之后,Duang的一下,发现结果真的是这样,他们使用了相同的Session了,也就是说,Tomcat1在接收到请求时,创建Session之后,会把Session持久化到Redis,而此时,Tomcat2也会取Redis里的Session数据,所以当请求访问Tomcat2的时候,也就有了Tomcat1里的Session,所以打印出来的SessionId是一样的。

 

             (具体Session如何持久化到Redis,另一个Tomcat如何获取Redis里的Session,何时获取Redis的Session,还需要有时间的时候再去研究,以上的言论,都是根据结果反推的,如有错误之处,恳请指出,以免误导到更多人——By Minutch)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值