原文: https://www.cnblogs.com/youzhibing/p/7348337.html  

HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保存在内存中的。但是我们把应用搭建成分布式的集群,然后利用LVS或Nginx做负载均衡,那么来自同一用户的Http请求将有可能被分发到多个不同的应用中。那问题来了,如何保证不同的应用能够共享同一份session数据呢?最简单的想法,就是把session数据保存到内存以外的一个统一的地方,例如Memcached/Redis等数据库中。那问题又来了,如何替换掉Servlet容器创建和管理的HttpSession的实现呢?

  1、利用Servlet容器提供的插件功能,自定义HttpSession的创建和管理策略,并通过配置的方式替换掉默认的策略。这方面其实早就有开源项目了,例如memcached-session-manager(可以参考负载均衡+session共享(memcached-session-manager实现),以及tomcat-redis-session-manager。不过这种方式有个缺点,就是需要耦合Tomcat/Jetty等Servlet容器的代码。

  2、设计一个Filter,利用HttpServletRequestWrapper,实现自己的 getSession()方法,接管创建和管理Session数据的工作。spring-session就是通过这样的思路实现的。

参考 spring-session之一 初探 spring-session

  本博客不涉及session解释,关于session大家自行去查资料;关于spring-session的相关概念大家可以去spring官网查阅(http://projects.spring.io/spring-session/)。

单机应用

  我们先来看下单机应用,应用很简单,就是在session中设置变量,然后获取这些设置的变量进行展示 ,具体代码如下

  pom.xml:

View Code

  web.xml

View Code

  SessionServlet.java

View Code

  index.jsp

View Code

  整个项目结构非常简单,如下如

  spring-session实现分布式集群session的共享(转)

  本地运行起来,效果如下

spring-session实现分布式集群session的共享(转)

  火狐浏览器与360浏览器代表不同的用户,各自都能获取各自session中的设置的全部变量,很正常,没毛病。

分布式集群应用

  单机应用中,session肯定没问题,就存在本地的servlet容器中,那么在分布式集群中会像单机一样正常吗?我们接着往下看

  搭建高可用的、实现负载均衡的分布式集群环境可参考nginx实现请求的负载均衡 + keepalived实现nginx的高可用,没搭建的需要先把分布式环境搭建起来

  没设置ession共享

    应用不变,代码与单机中的完全一致,将代码部署到分布式集群中去

    全部运行起来,效果如下

spring-session实现分布式集群session的共享(转)

    结果是:无论给session设置多少个值,session中的值都获取不到(离我的预期还是有差距,具体什么差距请看我的问题)

  spring-session实现session共享

    应用有所变化,代码与之前有所不同,具体区别如下(SessionServlet与index.jsp不变)

    pom.xml

View Code

    web.xml

spring-session实现分布式集群session的共享(转)
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <display-name>Archetype Created Web Application</display-name>

    <!-- spring-session config -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring-session.xml</param-value>
    </context-param>

    <!-- 这个filter 要放在第一个 -->
    <filter>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>session</servlet-name>
        <servlet-class>com.yzb.lee.servlet.SessionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>session</servlet-name>
        <url-pattern>/session</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>
spring-session实现分布式集群session的共享(转)

相关文章:

  • 2021-11-01
  • 2021-08-23
  • 2023-03-14
  • 2021-07-12
  • 2022-12-23
  • 2021-10-17
猜你喜欢
  • 2021-08-01
  • 2021-05-16
  • 2022-12-23
  • 2021-08-26
  • 2021-06-28
相关资源
相似解决方案