前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >SpringSession的使用了解下

SpringSession的使用了解下

作者头像
码农飞哥
发布2021-08-18 10:44:31
发布2021-08-18 10:44:31
49200
代码可运行
举报
文章被收录于专栏:好好学习好好学习
运行总次数:0
代码可运行

前言

单机环境下我们Session是存储在应用服务的内存中,但是在分布式环境 下,这种存储在应用服务器内存的方案显然不能实现session共享。本次我们将介绍spring-session实现分布式环境下Session共享方案,Session信息存储在redis中。

版本

spring-session 2.1.4.RELEASE

实现步骤

1. 引入依赖

代码语言:javascript
代码运行次数:0
运行
复制
    <!--redis的依赖-->
        <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>

spring-session-data-redis 依赖的作用是引入将Session写入redis的工具类。

2. 添加Session配置类

代码语言:javascript
代码运行次数:0
运行
复制
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = -1)
public class SessionConfig {}

maxInactiveIntervalInSeconds 属性用来设置Session失效的时间,单位是秒,-1表示永不失效。如果配置1小时失效则是60 * 60 * 1

3. 配置redis

代码语言:javascript
代码运行次数:0
运行
复制
spring.redis.host=192.168.226.111
spring.redis.database=0
spring.redis.port=6379

测试步骤

将同一个应用分别部署到两台服务上,然后通过nginx 实现负载均衡。 如下,我将应用分别部署在192.168.226.111和192.168.226.112两台服务器上,然后配置nginx 做了转发,配置如下:

代码语言:javascript
代码运行次数:0
运行
复制
upstream bootDemo {
    server 192.168.226.111:8080;
    server 192.168.226.112:8080;
} 
server {
    listen       80;
    server_name  shoptest.jss.com.cn;
     location /spring-boot-session/ {
            proxy_pass http://bootDemo/spring-boot-session/;
        }
}

调用登录接口,接口请求落到了192.168.226.112服务器上,由于是第一次请求,所以Tomcat会给当前会话生成一个Session。该Session中中保存了sessionId,creationTime,lastAccessedTime等信息。其中sessionId是4cebb851-b9b2-488e-9569-9ace9298bb67我们手动设置到Session中的用户信息是{"password":"123123","userName":"ceshi"}。 然后,我们我们通过 keys "*session*"指令可以找到 当前存入的用户如下图所示:

在这里插入图片描述 相关key的说明如下:

代码语言:javascript
代码运行次数:0
运行
复制
        //存储 Session 数据,数据类型hash,可以使用type查看
        Key:spring:session:sessions:4cebb851-b9b2-488e-9569-9ace9298bb67

        //Redis TTL触发Session 过期。(Redis 本身功能),数据类型:String
        Key:spring:session:sessions:expires:4cebb851-b9b2-488e-9569-9ace9298bb67

        //执行 TTL key ,可以查看剩余生存时间
        //定时Job程序触发Session 过期。(spring-session 功能),数据类型:Set
        Key:spring:session:expirations:133337740000

说明:前面的spring:session是Spring Session保存Session信息的前缀名称。 然后,我们请求获取用户信息接口,接口请求到了192.168.226.112服务器,可以获取到登录用户信息。

在这里插入图片描述

新场景

今天项目中碰到一个需求,A项目和B项目在同一个域名下,在A项目上登录之后,在B项目上就不需要在登录了,这要实现同域名下不同项目间的session共享。 然而,使用这个配置,

代码语言:javascript
代码运行次数:0
运行
复制
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = -1)
public class SessionConfig {}

并不能实现,原因是sessionid是放在cookie中缓存的,而这个cookie值的作用域(path)是指定项目名的,如下图所示:

在这里插入图片描述 所以同域名下不同项目名的项目是不能共享同一个session的,要想共享的话,只有修改Path,将其改到根目录下/。那么该怎么修改呢?首先,我们来看看spring-session是如何管理cookie的。 管理cookie的入口是SessionRepositoryFilter过滤器,而SessionRepositoryFilter过滤器中定义了httpSessionIdResolver属性,这个属性是CookieHttpSessionIdResolver类的实例,而在CookieHttpSessionIdResolver类中又定义了cookieSerializer属性,这个属性是DefaultCookieSerializer类的实例。那么我们最终就可以知道,cookie是通过DefaultCookieSerializer类来管理的。那么我们只需要重新设置DefaultCookieSerializer值就可以了。 那么怎么设置呢?通过看DefaultCookieSerializer类中设置CookiePath的方法getCookiePath,我们知道当cookiePath为空是默认取项目名,当cookiePath不为空时就取cookiePath。

代码语言:javascript
代码运行次数:0
运行
复制
    private String getCookiePath(HttpServletRequest request) {
        if (this.cookiePath == null) {
            return request.getContextPath() + "/";
        }
        return this.cookiePath;
    }

所以,我们只需要在SessionConfig类中重新设置DefaultCookieSerializer的cookiePath属性即可。设置如下:

代码语言:javascript
代码运行次数:0
运行
复制
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = -1)
public class SessionConfig {
    @Bean
    public DefaultCookieSerializer defaultCookieSerializer() {
        DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
        defaultCookieSerializer.setCookiePath("/");
        return defaultCookieSerializer;
    }
}

设置后的效果如下图所示:

在这里插入图片描述

在这里插入图片描述 同样的B项目也是同样的设置

源代码地址:

https://github.com/XWxiaowei/spring-boot-session-demo

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农飞哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 版本
  • 实现步骤
    • 1. 引入依赖
    • 2. 添加Session配置类
    • 3. 配置redis
  • 测试步骤
  • 新场景
  • 源代码地址:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档