基于Redis实现集中式Session服务

        在实际生产中,我们经常部署应用服务,在部署的过程中,要让用户无感知你的应用升级,这种方式可以通过负载均衡方式来实现灰度部署,如前些文章的Nginx方式来实现,通过负载均衡Nginx,更新某一台tomcat服务,再通知负载均衡Nginx,把Tomcat节点重新加载上去。依次这么做,把集群中的所有Tomcat都替换一次即可,就可以实现服务的灰度部署。

        那么问题来了,怎么去让用户是无感知的,也就是要实现用户的会话是可以共享的,基于Session共享的方式有很多方式,之前也做过分享,大概的方案有:

  1、使用数据库来存储Session

  2、使用Cookie来存储Session

  3、使用Redis来存储Sesssion

  4、使用Tomcat的session复制

  5、使用Memcached来存储Session

  本章将以Redis的方式来实现Tomcat的session共享;

       我们的例子使用了一台Nginx做负载均衡,后端挂接了两台Tomcat,且每台Tomcat的Session会话都保存到Redis数据库中。其中,Nginx配置为non-sticky运行模式,也即每一个请求都可以被分配到集群中的任何节点。当要上线新代码时,只需简单地取下Tomcat实例,此时所有的访问用户会被路由到活动的Tomcat实例中去,而且由于会话数据都是保存在redis数据库中,所以活跃用户并不会受影响。当Tomcat更新完毕,又可以把此节点加入到Nginx中。

     架构图:

      image.png

部署前提

    安装Nginx,安装Redis;

    不重点讲述,自行百度;或者看我之前的文章    

机器 服务
192.168.1.104 nginx
192.168.1.104 redis
192.168.1.105  Tomcat-81
192.168.1.105  Tomcat-82

方式一: 通过 tomcat-redis-session-manager 

   下载地址

         https://github.com/jcoleman/tomcat-redis-session-manager

      image.png

    先配置tomcat支持redis缓存策略 

         1.把jar拷贝到 $TOMCAT_HOME/lib/ 下面 

         2.修改$TOMCAT_HOME/conf/context.xml 

         在最后加上 

   <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />        
    <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" 
        host="192.168.1.104"       
        port="6379"             
        database="0"                 
        maxInactiveInterval="60" />

    Nginx配置 

          Nginx安装好以后,修改/usr/local/conf/nginx.conf配置文件,下边为最简配置。主要配置我们的tomcat服务器的地址+端口号。和他们的权重。

#user nobody;  
worker_processes  1;  
   
#error_log logs/error.log;  
#error_log logs/error.log  notice;  
#error_log logs/error.log  info;  
   
#pid       logs/nginx.pid;  
   
   
events {  
   #use   epoll;             #epoll是多路复用IO(I/OMultiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能  
   worker_connections  1024;  #单个后台work processes 进程最大的并发连接数  
}  
   
   
http {  
   include       mime.types;  
   default_type application/octet-stream;  
   
   #log_format  main  '$remote_addr - $remote_user [$time_local]"$request" '  
   #                  '$status$body_bytes_sent "$http_referer" '  
   #                 '"$http_user_agent" "$http_x_forwarded_for"';  
   
   #access_log  logs/access.log  main;  
   
   sendfile        on;  
   #tcp_nopush     on;  
    #设置超时时间  
   #keepalive_timeout  0;  
   keepalive_timeout  65;  
   #要代理的服务器的地址和端口号    weight 为权重,权重越大 被访问的次数越多, 压力越大!  
  upstream   myServer {  
   
         server 192.168.1.106:81;
         server 192.168.1.106:82;
  
   }  
   
   #gzip  on;  
    #监听80 端口  
   server {  
       listen       80;  
       #定义要使用的域名  
       server_name  localhost;  
   
       #charset koi8-r;  
      #设定本虚拟主机的访问日志  
       #access_log logs/host.access.log  main;  
       #配置前缀  即要转发到的ip+port  
       location / {  
           proxy_pass  http://myServer;  
          # root   html;  
          # index  index.html index.htm;  
       }  
   
       #error_page  404              /404.html;  
   
       # redirect server error pages to the static page /50x.html  
       #  
       error_page   500 502 503 504  /50x.html;  
       location = /50x.html {  
           root   html;  
       }  
    }  
}

  Session共享测试:

<body>

<%
//HttpSession session = request.getSession(true);

System.out.println(session.getCreationTime());

out.println("<br> SESSION ID:" + session.getId() + "<br>");

out.println("Session created time is :" + session.getCreationTime()
+ "<br>");
%>

</body>

      我们先对ip为104的进行访问,然后再对105的进行访问,我们会发现sessionid是不一样的。

image.png

image.png

 

       然后我们通过nginx 进行访问,我们刷新几次,会发现他会随机的选择服务器,加载页面,但是我们可以发现不管是访问的ip为104 还是105 的,他的sessionid都是一个,所以我们断定两台tomcat服务器已经共享session了! 每次刷新SessionID都是一致的,说明基于Redis的session共享方式部署成功.

  image.png

   这样我们的tomcat使用redis 实现session共享 就实现了,并且用ngnix 实现了负载均衡,但是我们想一下,如果我们使用一个nginx,如果该nginx所在的服务器,宕机了,那么我们的程序就挂掉了。那可以通过nginx+keepalived 实现高可用的负载均衡!

方式二:通过TomcatClusterRedisSessionManager  

      通过TomcatClusterRedisSessionManager  方式来实现redis共享,方式一比较早期的,没有实现redis3.0的集群,这种方式支持redis3.0 的集群方式;

  下载:

   https://github.com/ran-jit/TomcatClusterRedisSessionManager

   可以下载TomcatRedisSessionManager-1.0.zip包,解压后包括所需的jar包和配置文件。如下所示:   image.png

    将上面jar包拷贝到各个tomcat的lib目录下, 将RedisDataCache.properties拷到tomcat的conf目录下。

    配置文件修改

     (1)修改RedisDataCache.properties配置文件如下:

           # redis hosts ex: 127.0.0.1:6379, 127.0.0.2:6379, 127.0.0.2:6380, ….

           redis.hosts=192.168.187.131:6379 (redis服务器IP及端口号)

           # Redis Password

           redis.password= redis (REDIS配置文件中设置的密码)

            # set true to enable redis cluster mode

           redis.cluster.enabled=false

    (2)在tomcat/conf/context.xml文件中增加以下两行:

         <Valve className="com.r.tomcat.session.management.RequestSessionHandlerValve"/>

        <Manager className="com.r.tomcat.session.management.RequestSessionManager"/>

 

    (3)设置tomcat/conf/web.xml 中 session有效期

        <session-config>

             <session-timeout>60<session-timeout>

        <session-config>

     如果项目里也配置了session有效期,则以项目中有准。

       设置Session超时时间方式:

         http://zmx.iteye.com/blog/1846181

  效果测试,如方式一;  

未经允许,以非盈利目的转载他人文章是可以的,但必须注明原作者;但是,出于对作者的尊重,我们即使是非盈利为目的,也应该注明作者。

发表评论