目录

Session共享问题

目录

演示代码

Session共享及Session保持或者叫做Session一致性

  • Session问题原因分析

    出现这个问题的原因,从根本上来说是因为Http协议是无状态的协议。客户端和服务端在某次会话中产生的数据不会被保留下来,所以第二次请求服务端无法认识到你曾经来过, Http为什么要设计为无状态协议?早期都是静态页面无所谓有无状态,后来有动态的内容更丰富,就需要有状态,出现了两种用于保持Http状态的技术,那就是Cookie和Session。而出现上述不停让登录的问题,分析如下图:

    场景:nginx默认轮询策略

    https://img.zhaojq.top/20260727091646918.png
    示意图

  • 解决Session一致性的方案

    • Nginx的 IP_Hash 策略(可以使用)

      服务器重启Session丢失

      存在单点负载高的风险

      单点故障问题

    • Session复制(不推荐)

      多个tomcat之间通过修改配置文件,达到Session之间的复制

      性能低 内存消耗 不能存储太多数据,否则数据越多越影响性能

      延迟性

    • Session共享,Session集中存储(推荐)

      Session的本质就是缓存,那Session数据为什么不交给专业的缓存中间件呢?比如Redis

      优点:

      1. 能适应各种负载均衡策略
      2. 服务器重启或者宕机不会造成Session丢失
      3. 扩展能力强
      4. 适合大集群数量使用

      缺点:

      1. 对应用有入侵,引入redis交互代码
  • Spring Session使得基于Redis的Session共享应用起来非常简单

    1. 引入jar

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.session</groupId>
          <artifactId>spring-session-data-redis</artifactId>
      </dependency>
    2. 配置redis

      spring.redis.database=0
      spring.redis.host=127.0.0.1
      spring.redis.port=6379
    3. 添加注解

      @EnableRedisHttpSession
    4. 原理

      通过过滤器将session存储到了redis

    示例代码:spring-session-demo

    Tips: 如遇jsp 跳转404问题,增加如下编译配置

    <build>
            <resources>
                <resource>
                    <directory>src/main/webapp</directory>
                    <targetPath>META-INF/resources</targetPath>
                    <includes>
                        <include>**/**</include>
                    </includes>
                </resource>
            </resources>
    </build>