0

0

SpringBoot怎么整合Spring Session实现分布式会话

WBOY

WBOY

发布时间:2023-05-13 13:52:06

|

1211人浏览过

|

来源于亿速云

转载

spring 提供了处理分布式会话的解决方案:spring-session。spring-session 提供了对redis、mongodb、mysql 等常用存储的支持,spring-session 提供与 httpsession 的透明整合,这意味着开发人员可以使用 spring-session 支持的实现方式,切换 httpsession 至 spring-session。

一、配置及开发

Step 1、添加依赖

在项目的 pom.xml 文件中添加 Redis 和 Spring-Session 的依赖包。

        
                org.springframework.boot
                spring-boot-starter-data-redis
        
        
            org.springframework.session
            spring-session-data-redis
        

Step 2、配置 Redis 和 Spring-Session 持久化方式

笔者习惯使用 application.properties 作为 SpringBoot 的配置文件,也可以使用 application.yml 来配置。在 application.properties 配置文件中添加如下配置。

# 配置 Redis 服务器地址(此处是一个虚假地址)
spring.redis.host=10.211.12.6
# 配置 Redis 端口
spring.redis.port=6379
# 配置 Redis 密码
spring.redis.password=123456
# 其他 Redis 的配置还有很多,例如 Redis 连接池的配置,此处暂时只配置上述几项关键点
# spring session 配置
spring.session.store-type=redis

Step 3、使用 JSON 序列化机制

Spring-Session 默认使用 JDK 序列化机制,要求类实现 Serializable 接口,序列化后是二进制字节数组,不易看懂。使用 JSON 序列化机制,序列化后的字符串容易看懂。

package com.test.conf;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.RedisSerializer;

// spring session 使用 json 序列化机制
@Configuration
public class SessionConfig {
    @Bean
    public RedisSerializer springSessionDefaultRedisSerializer() {
        return new GenericFastJsonRedisSerializer();
    }
}

Step 4、在 SpringBoot 启动类中添加 @EnableRedisHttpSession 注解,开启 Spring-Session

package com.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
// 开启 Spring-Session
@EnableRedisHttpSession
// @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800, redisNamespace = "test:session")
public class TestSessionAppApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestSessionAppApplication.class, args);
    }
}

 打上 @EnableRedisHttpSession 注解即可开启 Spring-Session。注解有几个参数可以单独设置,其中 maxInactiveIntervalInSeconds 表示 Session 过期时间,默认值是 30 分钟;redisNamespace 表示 Session 在 Redis 中存储时的命名空间,即 Session 在 Redis 中存储的键名前缀,默认值是 “spring:session”,在实际项目中,可能不同的系统为了节约资源,会使用同一个 Redis,为了区分不同系统的 Session,可以为每个系统设置单独的命名空间。

二、测试

2.1 controller 层编写测试 demo

    @RequestMapping(value = "testSession")
    public String testSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        log.info("sessionId:[{}]", session.getId());
        session.setAttribute("name", "Lucy");
        session.setAttribute("age", "20");
        return session.getAttribute("name").toString();
    }

2.2 测试过程

同时以不同的端口 9001/9002 启动 SpringBoot 项目,在本机电脑上模拟分布式集群中的不同节点。用谷歌浏览器打开链接 http://localhost:9001/testSession,服务端打印日志如下所示。

sessionId:[5c417104-4f6d-430d-b569-cbc1e19cdf02]

客户端登录 Redis 服务器,查看 Redis 中的 Session 内容。

[testuser@vm ~]$ redis-cli -h 10.211.12.6 -p 6379
10.211.12.6:6379> auth 123456
OK
10.211.12.6:6379> keys *
1) "spring:session:expirations:1658127780000"
2) "spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02"
3) "spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02"

Redis 会为每个 RedisSession 存储三个键值对(以下简称 key-value):

  • 第一个 key-value 存储这个 Session 的 Id,是一个 Set 类型的 Redis 数据结构。这个 key 中的最后的 1658127780000 值是一个时间戳,根据这个 Session 过期时刻滚动至下一分钟而计算得出。

    Build AI
    Build AI

    为您的业务构建自己的AI应用程序。不需要任何技术技能。

    下载
  • 第二个 key-value 用来存储 Session 的详细信息,是一个 Hash 类型的 Redis 数据结构,包括 Session 的最近访问时间(lastAccessedTime)、过期时间间隔(maxInactiveInterval,默认是 30 分钟,这里保存的秒值)、创建时间(creationTime)、sessionAttr 等等。

  • 第三个 key-value 用来表示 Session 在 Redis 中的过期时间,是一个 String 类型的 Redis 数据结构。这个 key-value 不存储任何有用数据,只是为表示 Session 过期而设置。这个 key 在 Redis 中的过期时间即为 Session 的过期时间间隔,可以用 ttl 命令查看该 key 的过期时间,即为 Session 的过期时间。

本次测试时,Redis 中的数据详情如下所示。

10.211.12.6:6379> type spring:session:expirations:1658127780000
set
10.211.12.6:6379> smembers spring:session:expirations:1658127780000
1) "\"expires:5c417104-4f6d-430d-b569-cbc1e19cdf02\""
10.211.12.6:6379>
10.211.12.6:6379> type spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02
hash
10.211.12.6:6379> hgetall spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02
 1) "lastAccessedTime"
 2) "1658125969794"
 3) "maxInactiveInterval"
 4) "1800"
 5) "creationTime"
 6) "1658125925139"
 7) "sessionAttr:age"
 8) "\"20\""
 9) "sessionAttr:name"
10) "\"Lucy\""
10.211.12.6:6379>
10.211.12.6:6379> type spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02
string
10.211.12.6:6379> get spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02
""
10.201.42.26:6379>

查看浏览器 Cookie,此时浏览器已经有了一个正在使用的 Cookie,见下图。

SpringBoot怎么整合Spring Session实现分布式会话

刷新浏览器,后端打印的 SessionId 不变,Redis 中的 Session 内容未新增,浏览器正常返回内容。说明本节点操作 Session 正常。

同一浏览器,打开另外一个测试端口链接 http://localhost:9002/testSession,浏览器自动携带 Cookie,后端打印内容相同,Redis 内容相同(过期时间已更新),说明集群节点之间共享了 Session。

三、Spring-Session 的缺点

虽然 Spring-Session 提供了一种简单易用,近乎透明的集成方式,使得支持集群会话变得微不足道,但是实际上 Spring-Session 是有些缺陷的。

  • 无法做到 Session 的过期以及销毁事件的实时发布;

  • 序列化方式可能对一些特定类型的会话,支持的不是很好;

  • Redis 存储一个会话需要 3 个 键值,占用空间稍微大些;

  • 在高并发场景下,Session 因为不是 CAS(Compare And Set) 操作,所以可能存在一些并发问题(小问题)。

虽然 Spring-Session 存在一些缺点,但整体来说还是可用性很高的。此外自己可以写一套过滤器,优化 Spring-Session 的缺点,实现分布式会话。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

653

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

244

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

280

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

513

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

250

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

384

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

522

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

594

2023.08.14

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Redis6入门到精通超详细教程
Redis6入门到精通超详细教程

共47课时 | 5.1万人学习

Spring中文手册
Spring中文手册

共0课时 | 0人学习

Laravel 5.8 中文文档手册
Laravel 5.8 中文文档手册

共74课时 | 82万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号