[springboot专栏]利用redis实现集群多节点应用session共享

一、spring session 共享的实现原理

单个应用的session应用

在这里插入图片描述

  • 用户登陆之后,将状态信息保存到session里面。服务端自动维护sessionid,即将sessionid写入cookie。
  • cookie随着HTTP响应,被自动保存到浏览器端。
  • 当用户再次发送HTTP请求,sessionid随着cookies被带回服务器端
  • 服务器端根据sessionid,可以找回该用户之前保存在session里面的数据。

集群应用的Session共享

  • 同一IP(域名),不同端口,在同一个浏览器cookies是共享的。不同IP(域名)的Cookies,在同一个浏览器Cookies肯定不共享的。对于这种情况需要在集群应用的前面加上负载均衡器逆向代理,如:nginx,haproxy。让客户端看上去访问的是同一个IP(代理IP),从而浏览器认为基于这个IP的Cookies是共享的。
  • SESSION正常是由Servlet容器来维护的(内存里面,每个服务器内存是不共享的),这样SESSION就无法共享。如果希望Session共享,就需要把sessionID的存储放到一个统一的地方,如:redis。SessionID的维护交给Spring session则更加方便。
  • 除了Cookies可以维持Sessionid,Spring Session还提供了了另外一种方式,就是使用header传递SESSIONID。目的是为了方便类似于手机这种没有cookies的客户端进行session共享。

在这里插入图片描述

不要把跨域请求和cookies跨域名的概念搞混了。同源策略是要求IP、端口、协议全一致,不一致的请求就是跨域请求。但cookies是可以跨域共享的,但是不能跨域名(IP)共享。

二、集成Spring session

1.引入spring-session-redis的maven依赖

项目内引入spring-session-data-redis,配合spring-boot-starter-data-redis

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

2.配置启用Redis的httpSession

在启动类上方加上注解,启动SpringSession管理应用的session,并设置session数据的有效期30分钟

@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 30 * 60 * 1000)

3.配置redis链接信息(application.yml)

配置redis链接信息


spring:

    redis:
      database: 0
      host: 这里填写redis服务ip
      password: 这里填写redis服务密码
      port: 6379

4.测试

做好上文的配置之后,并加入如下的测试代码,后文测试的时候会用到

@Controller
public class SessionController {
    
    

  @RequestMapping(value="/uid",method = RequestMethod.GET)
  public @ResponseBody
  String uid(HttpSession session) {
    
    
    return "sessionId:" + session.getId();
  }

}

5. 一个项目多个端口启动

为了实现验证一个应用的多个实例的session共享,我们启动多个服务实例
在这里插入图片描述

  • 点击edit configuration ,取消勾选single instance only(只允许单节点运行)。在比较新的版本中这个勾选框变成了Allow parallel run(允许多实例并发运行),那你就给它勾选上。总之我们是要运行多实例。
  • 复制一份当前配置,在environment选项中的vm options 中设置不同的端口号
-Dserver.port=8889 -Dserver.httpPort=89 -Dspring.profiles.active=dev -Ddebug
-Dserver.port=8888 -Dserver.httpPort=88 -Dspring.profiles.active=dev -Ddebug

三、测试

依次访问,看看效果.通过返回值session.getId()即:sessionid来判断,如果sessionid一致,则证明session共享成功了。

用浏览器访问下面的地址,自己看一下效果,再理解一下。

在这里插入图片描述

因为我们在同一台机器上启动多个实例,ip相同所以session是共享的。如果你在不同的服务器上启动多个实例(IP)不同,你需要在应用前方加上负载均衡逆向代理才可以实现session共享。(如本文首图)

猜你喜欢

转载自blog.csdn.net/hanxiaotongtong/article/details/122906709