美文网首页程序小寨
Nginx+Tomcat+Redis实现Session共享

Nginx+Tomcat+Redis实现Session共享

作者: 梦中一点心雨 | 来源:发表于2018-12-18 14:40 被阅读8次

    之前的博文中简单的介绍了一下Nginx的负载均衡配置,比较简单,但是如果实现多台服务器之间的session共享就是一个难题了。

    经过查资料,找到了几种解决session共享的方案。

    • 不适用session,换作cookie

      能把session改成cookie,就能避开session的一些弊端,也有资料表明在集群系统中不能使用session。但是博主思考再三,公司项目的session中存储一些比较重要的信息,在以后的业务中也会使用session中的数据,所以直接使用cookie这种方案果断舍弃。
      
    • 应用服务器自行实现共享

      让服务器自行实现session共享,就需要提供一个后端服务器都能访问的公共容器来存储session,比如redis或者memcache,当系统需要获取session时,直接从redis或memcache中获取即可。
      

      以上两种方式都与Nginx没多大关系了。下面说说使用nginx如何处理

    • ip_hash

      之前的博客中对upstream的几种方式做了介绍,相信大家还记得ip_hash的介绍吧,每个请求按访问ip的hash结果分配,这样每个访问固定访问一个后端服务器。
      这样一来这个ip下的某个客户端和某个后端服务器就能建立稳固的session。这样每个客户端都只对应一个服务器,那就不存在需要共享session的需要了,不过只用ip这个因子来分配后端,所以还是存在一些缺陷,不能在以下情况下使用:
      1、nginx不是最前端的服务器。ip_hash要求nginx一定是最前端的服务器,否则nginx就得不到正确的ip,也就不能根据ip来分配后端了。比如squid(一个高性能的代理缓存服务器)作为最前端,那么nginx只能获取到squid所在服务器的ip地址,这种分流方式肯定会混乱的。
      2、nginx的后端还有其他方式的负载均衡。如果nginx后端又有其他的负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台服务器上。
      
    • upstream_hash

      为了解决ip_hash的一些问题,可以使用upstream_hash这个第三方模块,这个模块大多数情况下是用作url_hash的,但是并不妨碍将它用来做session共享;
      这种方式不是很理解,就不做累述了,以后再慢慢研究。读者可自行查找资料学习。
      

    来自于网络上的方案介绍完了,接下来说说博主项目中的实际操作。

    博主最初的打算是使用redis来缓存系统数据,刚好也可以实现session共享。可惜,客户公司方面服务器资源不够,不让使用redis,上面第二种方案瞬间被阉割掉了,有点不爽。这里必须吐槽吐槽客户公司。

    由于不让使用redis,所以只能使用第三种方式了,这里就不做太多的累述了,比较简单,配置nginx负载均衡的时候将upstream的方式配置为ip_hash即可,具体配置方式在上篇“Nginx负载均衡配置”中已有例子,可做参考。

    简单的解释一下公司项目架构,公司项目采用前后台分离的架构,前端页面使用angularJS实现一种单页面应用,后台服务则使用SpringBoot为前端提供数据服务,后台开发者只需要关注后端逻辑,然后将前端需要的数据转为json传给前端,而不需要去考虑页面的跳转等,而前端人员也不需要关注后台逻辑,可以全身心的提供前端的用户体验度,最主要的是前后台分离后,系统开发职责划分的更加清晰。

    关于前后台分离方案,这个博客讲的比较好,读者可做参考。

    这样就完了?没有,这就完了这篇博客也太水了,虽然客户公司不让使用redis,但是博主还是自己抽时间使用nginx+tomcat+redis来自己实现session共享。

    ------------------------------------------------------------------这是一个分隔线-------------------------------------------------------------------

    1、软件准备

    因为是自己玩,所以直接在windows上开工了。

    nginx-1.11.5,apache-tomcat-7.0.55,redis-2.6.12(windows版)

    读者可从这里下载。其中有三个jar包最为重要:

    commons-pool-1.6.jar,jedis-2.1.0.jar,tomcat-redis-session-manager-tomcat7.jar,在软件包中的tomcat的lib目录下可找到。

    2、配置tomcat

    在tomcat中的context.xml文件中加入以下内容

    <Valve  className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
    <Manager className="com.radiadesign.catalina.session.RedisSessionManager"
        host="localhost" 
        port="6379"
        database="0" 
        maxInactiveInterval="60" />
    

    将配置好的tomcat三份,分别命名为apache-tomcat-7.0.55-1,apache-tomcat-7.0.55-2,apache-tomcat-7.0.55-3,然后去将每个tomcat的端口改掉,分别改为8081,8082,8083

    3、配置Nginx

    将三个tomcat服务器用nginx代理,

    upstream  localhost   {
        server   localhost:8081 weight=1;  
        server   localhost:8082 weight=1;  
        server   localhost:8083 weight=1; 
    }
    

    4、测试页面

    在tomcat的webapp目录下新建test目录,在test中新建index.jsp,然后给三个tomcat都拷贝一份

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    <%
        out.println(request.getSession().getId());
    %>
    </body>
    </html>
    

    这可能是可与Hello,World媲美的页面了。

    5、启动测试

    先启动redis,在启动三个tomcat,最后再启动nginx,然后访问页面。

    有两种访问方式:

    • 直接访问三个tomcat,【http://localhost:808x/test/index.jsp】,查看页面打印出的sessionId是否一致。
    • 多次访问nginx,【http://localhost:80/test/index.jsp】,同时配置Nginx时将upstream配置为轮询,使用上面路径访问时会将请求轮流转发到三台服务器上,确实此时页面上的sessionId是否一致

    好了,这种session共享完成。

    这种Session共享是基于Tomcat完成的,不会侵入项目。当前还有一种实现Session共享的方式,Spring全家桶中,Spring Session框架就是专门做Session管控的。

    相关文章

      网友评论

        本文标题:Nginx+Tomcat+Redis实现Session共享

        本文链接:https://www.haomeiwen.com/subject/qeclkqtx.html