Spring Session

一、 HttpSession 回顾

1 什么是 HttpSession

是 JavaWeb 服务端提供的用来建立与客户端会话状态的对象。

二、 Session 共享

1 什么是 Session 共享

是指在一个浏览器对应多个 Web 服务时,服务端的 Session 数据需要共享。
2 Session 共享应用场景
1) 单点登录
2) Web 服务器集群等场景都需要用到
3 Session 共享常见的解决方案
3.1Session 复制
通过对应用服务器的配置开启服务器的 Session 复制功能,在集群中的几台服务器之间
同步 Session 对象,使得每台服务器上都保存所有的 Session 信息,这样任何一台宕机都不
会导致 Session 的数据丢失,服务器使用 Session 时,直接从本地获取。这种方式的缺点也
比较明显。因为 Session 需要时时同步,并且同步过程是有应用服务器来完成,由此对服务
器的性能损耗也比较大。
3.2Session 绑定
利用 hash 算法,比如 nginx 的 ip_hash,使得同一个 Ip 的请求分发到同一台服务器上。
这种方式不符合对系统的高可用要求,因为一旦某台服务器宕机,那么该机器上的
Session 也就不复存在了,用户请求切换到其他机器后么有 Session,无法完成业务处理。
3.3利用 Cookie 记录 Session
Session 记录在客户端,每次请求服务器的时候,将 Session 放在请求中发送给服务器,
服务器处理完请求后再将修改后的 Session 响应给客户端。这里的客户端就是 cookie。
利用 cookie 记录 Session 的也有缺点,比如受 cookie 大小的限制,能记录的信息有限,
安全性低,每次请求响应都需要传递 cookie,影响性能,如果用户关闭 cookie,访问就不正
常。3.4Session 服务器
Session 服务器可以解决上面的所有的问题,利用独立部署的 Session 服务器统一管理
Session,服务器每次读写 Session 时,都访问 Session 服务器。
对于 Session 服务器,我们可以使用 Redis 或者 MongoDB 等内存数据库来保存 Session
中的数据,以此替换掉服务中的 HttpSession。达到 Session 共享的效果。
三、 什么是 Spring Session
Spring Session 是 Spring 的项目之一。Spring Session 提供了一套创建和管理 Servlet
HttpSession 的方案,默认采用外置的 Redis 来存储 Session 数据,以此来解决 Session 共享的
问题。
四、 Spring Session 的使用
1 安装 Redis
第一步 需要在 linux 系统中安装 gcc
命令:yum install -y gcc-c++
第二步 需要将下载好的 redis 压缩包添加到 linux 服务器中
版本:redis-3.0.0.tar.gz
redis 的版本:副版本号奇数版本号是测试版,不建议在生产环境中使用。
偶数版本时稳定版建议在生产环境中使用。
3.0 版本更新比较大。集成了集群技术
第三步 解压压缩包
命令:tar -zxvf redis......
第四步 编译 redis
命令:进入 redis 的解压完毕的根目录下 执行命令:make
第五步 安装 redis
命 令 : 进 入 redis 的 解 压 完 毕 的 根 目 录 下 , 执 行 命 令 : make install
PREFIX=/usr/local/redis
第六步:启动 redis
1,前端启动
在 bin 目录下执行命令: ./redis-server
(ctrl+c)退出 redis
2.后端启动(1)先将 redis 解压目录下的 redis.conf 文件拷贝到 安装好的 redis 的 bin 目录下
命令:cp redis.conf /usr/local/redis/bin
(2)修改拷贝过来的 redis.conf 配置文件
命令:vim redis.conf
将 daemonize no 改为 yes
(3)启动 redis
在 bin 目录下执行命令:./redis-server redis.conf
(4)查看 redis 启动是否成功
输入命令:ps aux|grep redis
(5) 关闭 redis 的命令
./redis-cli shutdown
第七步:测试 redis
在 bin 目录下启动 redis 自带的客户端 ./redis-cli
常见 redis 命令:
ping--->pong
2 搭建案例环境
2.1版本介绍
JDK:1.8
Spring Boot:2.1.6.RELEASE
Spring Session:Bean-SR3
2.2创建项目
创建父工程 spring_session
 

2.3修改 POM 文件添加坐标依赖

 
修改父工程 POM 文件
 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>spring_session</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>session_service1</module>
<module>session_service2</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1..RELEASE</version>
</parent><dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-bom</artifactId>
<version>Bean-SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--web Starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Redis Starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
<!--Spring session data redis-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!--Lettuce 是一个基于Netty的NIO方式处理Redis的技术-->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
</dependencies>
</project>

3 添加配置文件

 

3.1session_service1

 
#服务端口
server:
port: 8080
spring:
redis:
host: 192.168.70.156 #Redis 配置
port: 6379
password:
database: 0
 

3.2session_service2

#服务端口
server:
port: 8081
spring:
redis:
host: 192.168.70.156 #Redis 配置
port: 6379
password:
database: 0
 

4 创建启动类

 

4.1session_service1

 
@SpringBootApplication@EnableRedisHttpSession
public class Service1Application {
public static void main(String[] args){
SpringApplication.run(Service1Application.class,args);
}
}

4.2session_service2

 
@SpringBootApplication
@EnableRedisHttpSession
public class Service2Application {
public static void main(String[] args){
SpringApplication.run(Service2Application.class,args);
}
}
 

5 编写测试代码测试效果

 

5.1session_service1

 

5.1.1创建 Controller

@RestController
@RequestMapping("service1")
public class WebController {
@RequestMapping("/setMsg")
public String setMsg(HttpSession session,String msg){
session.setAttribute("msg",msg);
return "ok";
}
}

5.2session_service2

 

5.2.1创建 Controller

 
@RestController
@RequestMapping("/service2")
public class WebController {
@RequestMapping("/getMsg")
public String getMsg(HttpSession session){
String msg = (String) session.getAttribute("msg");
return msg;
}
}
 

5.2.2测试

6 共享自定义对象

 

6.1创建 Users 实体类

public class Users implements Serializable {
private String username;
private String userpwd;
public String getUsername() {
return username;
}public String getUserpwd() {
return userpwd;
}
public void setUsername(String username) {
this.username = username;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
}

6.2修改 session_service1 的 controller

@RestController
@RequestMapping("service1")
public class WebController {
@RequestMapping("/setMsg")
public String setMsg(HttpSession session,String msg){
session.setAttribute("msg",msg);
return "ok";
}
/**
* 获取 Users 信息,保存到 HttpSession 中
*/
@RequestMapping("/addUsers")
public String addUsers(HttpSession session, Users users){
session.setAttribute("u",users);
return "ok";
}
}

6.3修改 session_service2 的 controller

@RestController@RequestMapping("/service2")
public class WebController {
@RequestMapping("/getMsg")
public String getMsg(HttpSession session){
String msg = (String) session.getAttribute("msg");
return msg;
}
/**
* 获取 HttpSession 中的 Users 对象
*/
@RequestMapping("/getUsers")
public Users getUsers(HttpSession session){
Users users = (Users) session.getAttribute("u");
return users;
}
}

6.4测试

7 Spring Session 的 Redis 存储结构

 
spring:session:expirations:(Set 结构)用户 ttl 过期时间记录
这个 k 中的值是一个时间戳,根据这个 Session 过期时刻滚动至下一分钟而计算得出。
这个 k 的过期时间为 Session 的最大过期时间 + 5 分钟。
spring:session:sessions:(Hash 结构)
maxInactiveInterval:过期时间间隔
creationTime:创建时间lastAccessedTime:最后访问时间
sessionAttr:Attributes 中的数据
存储 Session 的详细信息,包括 Session 的过期时间间隔、最后的访问时间、attributes
的值。这个 k 的过期时间为 Session 的最大过期时间 + 5 分钟。
spring:session:sessions:expires:(String 结构)过期时间记录
这个 k-v 不存储任何有用数据,只是表示 Session 过期而设置。
这个 k 在 Redis 中的过期时间即为 Session 的过期时间间隔。
 

8 设置 Session 的失效时间

 

8.1在注解中设置失效时间

@SpringBootApplication
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=)
public class Service1Application {
public static void main(String[] args){
SpringApplication.run(Service1Application.class,args);
}
}

9 @EnableRedisHttpSession 注解讲解

9.1maxInactiveIntervalInSeconds

设置 Session 的失效时间,单位为秒。默认(1800 秒)30 分钟。

9.2redisNamespace

为键定义唯一的命名空间。该值用于通过更改前缀与默认 spring:session 隔离会话

9.3redisFlushMode

Redis 会话的刷新模式。默认值为“保存”

9.4cleanupCron

过期会话清理作业的 cron 表达式。默认值("0 * * * * *")每分钟运行一次。10 更换 Spring Session 的序列化器
Spring Session 中默认的序列化器为 jdk 序列化器,该序列化器效率低下,内存再用大。
我们可以根据自己的需要更换其他序列化器,如 GenericJackson2JsonRedisSerializer 序列化
器。

10.1在配置类中创建自定义序列化器

@Configuration
public class SpringSessionConfig {
/**
* 更换默认的序列化器
*
*/
@Bean("springSessionDefaultRedisSerializer")
public RedisSerializer defaultRedisSerializer(){
return getSerizlizer();
}
/**
* 定义序列化器
*/
private RedisSerializer getSerizlizer(){
return new GenericJackson2JsonRedisSerializer();
}
}

10.2测试

Spring Session MongoDB
一、 Spring Session MongoDB 简介
1 什么是 Spring Session MongoDB
Spring Session MongoDB 是 Spring Session 的二级项目。其功能与 Spring Session 是相同
的。Spring Session MongoDB 提供了一个 API 和实现,用于通过利用 Spring Data MongoDB
来管理存储在 MongoDB 中的用户会话信息。
2 他与 Spring Session 的区别
Spring Session 与 Spring Session MongoDB 的作用是相同的。都是来解决 Session 共享问
题。不同的是 Spring Session 默认的是依赖于 Redis 作为数据缓存平台,而 Spring Session
MongoDB 是依赖于 MongoDB 来作为数据缓存平台的。
二、 Spring Session MongoDB 的使用
1 安装 MongoDB
1.1下载 MongoDB
mongodb-linux-x86_64-4.0.9.tgz
1.2解压 tgz 文件
[root@localhost temp]# tar -zxf mongodb-linux-x86_64-4.0.9.tgz
1.3创建数据库目录
[root@localhost etc]# mkdir -p data/db
1.4创建日志文件
[root@localhost etc]# touch mongodb.log
1.5创建配置文件
[root@localhost etc]# vim mongodb.conf1.6启动 MongoDB
[root@localhost bin]# ./mongod --cofnig /usr/local/mongodb/etc/mongodb.conf
1.7创建 sxt 库
> use sxt
2 搭建案例环境
2.1技术版本
JDK:1.8
Spring Boot:2.1.6RELEASE
Spring Session MongoDB:Bean-SR3
2.2创建项目 
 

2.3修改 POM 文件添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>session_mongodb</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>session_mongo1</module>
<module>session_mongo2</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-bom</artifactId>
<version>Bean-SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongodb</artifactId>
</dependency>
</dependencies>
</project>
2.4添加配置文件
2.4.1Session_monog1
#配置服务的端口
server:
port: 8080
#配置 MongoDB 的链接信息
spring:
data:
mongodb:
host: 192.168.70.156
port: 27017
database: sxt
session:
store-type: mongodb
2.4.2Session_mongo2
#配置服务的端口
server:
port: 8081
#配置 MongoDB 的链接信息
spring:data:
mongodb:
host: 192.168.70.156
port: 27017
database: sxt
session:
store-type: mongodb
2.5创建启动类
2.5.1Session_mongo1
@SpringBootApplication
@EnableMongoHttpSession
public class Mongo1Application {
public static void main(String[] args){
SpringApplication.run(Mongo1Application.class,args);
}
}
2.5.2Session_mongo2
@SpringBootApplication
@EnableMongoHttpSession
public class Mongo2Application {
public static void main(String[] args){
SpringApplication.run(Mongo2Application.class,args);
}
}3 编写测试代码
3.1Session_mongo1
@RestController
@RequestMapping("/service1")
public class WebController {
/**
* 将数据存放到 HttpSession 中
*/
@RequestMapping("/setMsg")
public String getMsg(HttpSession session,String msg){
session.setAttribute("msg",msg);
return "ok";
}
}
3.2Session_mongo2
@RestController
@RequestMapping("/service2")
public class WebController {
/**
* 获取 HttpSession 中的数据
*/
@RequestMapping("/getMsg")
public String getMsg(HttpSession session){
String msg = (String) session.getAttribute("msg");
return msg;
}
}
3.3修改 MongoDB 的配置文件添加 bind_ip
dbpath=/usr/local/mongodb/data/db
logpath=/usr/local/mongodb/log/mongodb.logport=27017
fork=true
bind_ip=0.0.0.0
3.4测试 
 

4 共享自定义对象
4.1创建 Users 类
public class Users implements Serializable {
private String username;
private String userpwd;
public String getUsername() {
return username;
}
public String getUserpwd() {
return userpwd;
}
public void setUsername(String username) {
this.username = username;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}}
4.2session_mongo1
@RestController
@RequestMapping("/service1")
public class WebController {
/**
* 将数据存放到 HttpSession 中
*/
@RequestMapping("/setMsg")
public String getMsg(HttpSession session,String msg){
session.setAttribute("msg",msg);
return "ok";
}
/**
* 获取数据封装 Users
*/
@RequestMapping("/setUsers")
public String setUsers(HttpSession session, Users users){
session.setAttribute("users",users);
return "ok";
}
}
4.3session_mongo2
@RestController
@RequestMapping("/service2")
public class WebController {
/**
* 获取 HttpSession 中的数据
*/
@RequestMapping("/getMsg")public String getMsg(HttpSession session){
String msg = (String) session.getAttribute("msg");
return msg;
}
/**
* 从 HttpSession 中获取 Users
*/
@RequestMapping("/getUsers")
public Users getUsers(HttpSession session){
Users users = (Users) session.getAttribute("users");
return users;
}
}
4.4测试 
 

5 Spring Session MongoDB 的存结构
{
"_id"
:
"fe3f6cea-c3e2-426b-a47a-cf21c5b848cb",
"created"
:
ISODate("2019-07-12T12:46:48.916Z"), "accessed" : ISODate("2019-07-12T12:46:48.919Z"),
"interval" : "PT30M", "principal" : null, "expireAt" : ISODate("2019-07-12T13:16:48.919Z"),
"attr"
:
BinData(0,"rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9h
ZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAFdXNlcnN
zcgAcY29tLmJqc3h0Lm1vbmdvLmRvbWFpbi5Vc2Vyc5EM02IkljhzAgACTAAIdXNlcm5hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMAAd1c2VycHdkcQB+AAR4cHQABWFkbWludAAF
YWRtaW54") }
6 设置 Session 失效时间
@SpringBootApplication
@EnableMongoHttpSession(maxInactiveIntervalInSeconds=10)
public class Mongo1Application {
public static void main(String[] args){
SpringApplication.run(Mongo1Application.class,args);
}
}
7 @EnableMongoHttpSession 注解讲解
maxInactiveIntervalInSeconds:设置 Session 失效时间
collectionName:设置 MongoDB 的 Collections 的名称
8 更换 Spring Session MongoDB 的序列化器
Spring Session MongoDB 默认使用的是 JDK 序列化器。
8.1创建配置类添加 Jackson 序列化器
/**
* 更换 Spring Session MongoDB 的序列化器
*/
@Configuration
public class SessionMongoConfig {
@Bean
JacksonMongoSessionConverter mongoSessionConverter() {
return new JacksonMongoSessionConverter();
}
}8.2修改实体类,添加@JsonAutoDetect 注解
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility
.ANY)
public class Users implements Serializable {
private String username;
private String userpwd;
public String getUsername() {
return username;
}
public String getUserpwd() {
return userpwd;
}
public void setUsername(String username) {
this.username = username;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
}
8.3测试

springsession的更多相关文章

  1. 使用SpringMVC集成SpringSession的问题

    最近在使用SpringSession时遇到一个问题,错误日志如下: Exception sending context initialized event to listener instance o ...

  2. spring-session整合

    如果项目之前没有整合过spring-data-redis的话,这一步需要先做,在maven中添加这两个依赖: <dependency>     <groupId>org.spr ...

  3. [Spring] spring-session + JedisPool 实现 session 共享

    1.至少导入四个jar包: jedis spring-session spring-data-redis commons-pool2 2.bean配置 <?xml version="1 ...

  4. 分布式cookie-session的实现(spring-session)

    分布式cookie-session的实现(spring-session) 本文使用的spring-session版本为 1.0.0,地址为: https://github.com/spring-pro ...

  5. 架构设计之Spring-Session分布式集群会话管理

    前言 通常在web开发中,回话管理是很重要的一部分,用于存储与用户相关的一些数据.对于JAVA开发者来说,项目中的session一般由Tomcat或者jetty容器来管理. 特点介绍 尽管使用特定的容 ...

  6. springboot 集成spring-session redis 实现分布式session

    gradle 添加依赖 compile("org.springframework.session:spring-session:1.3.0.RELEASE") compile(&q ...

  7. 初试spring-session

    一.简介 spring-session提供了用户会话信息管理的API和实现. 它将取代容器中的HttpSession.在没有容器会话集群方案的情况下,使得支持会话集群微不足道. 它支持在一个浏览器实例 ...

  8. spring-session实现分布式集群session的共享

    前言 HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保存在内存中的.但是我们把应用搭建成分布式的集群,然后利用LVS或Nginx做负载均衡,那么来自同一用户 ...

  9. spring-session 共享

    Spring session 共享 一.引入依赖 <dependency> <groupId>redis.clients</groupId> <artifac ...

  10. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

随机推荐

  1. 没有学历如何从事Java开发?

    学历成了当今社会一个衡量一个人能力的标准,未来只会越来越深入,也有的人说不要总是把学历挂嘴边,学历并不能代表能力,确实学历不能代表能力,但是学历是能代表一个的人学习深度,也是在职场上必备的一个敲门砖. ...

  2. 2019 HL SC day10

    10天都过去了 4天都在全程懵逼.. 怎么可以这么难啊 我服了 现在想起依稀只记得一些结论 什么 反演? 什么后缀自动机?什么组合数的应用?什么神仙东西 ,不过讲课人的确都是神仙.(实名羡慕. mzx ...

  3. time模块 random模块

    time模块 time.sys等模块是C语言实现的,内置到了python解释器的.而不是py文件. 导入模块的时候,优先到python解释器,然后才会找py文件. #时间戳 #计算 # print(t ...

  4. 如何查看Docker容器环境变量,如何向容器传递环境变量

    1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! 了解Docker容器的运行环境非常重要,我们把应用放在容器里执行,环境变量会直接影响程序的执行效果.所以我们要知道容器内部的 ...

  5. CentOS7安装MinIO教程,并在C#客户端WPF中实现监控上传进度

    MinIO的详细介绍可以参考官网(https://min.io/product/overview). 简单来说它是一个实现了AWS S3标准的100%开源的,可商用的( Apache V2 licen ...

  6. C#LeetCode刷题之#11-盛最多水的容器(Container With Most Water)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3615 访问. 给定 n 个非负整数 a1,a2,...,an,每 ...

  7. C#LeetCode刷题之#344-反转字符串​​​​​​​(Reverse String)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3933 访问. 编写一个函数,其作用是将输入的字符串反转过来. 输 ...

  8. LeetCode 646 最长数对链详解

    题目描述 给出 n 个数对. 在每一个数对中,第一个数字总是比第二个数字小. 现在,我们定义一种跟随关系,当且仅当 b < c 时,数对(c, d) 才可以跟在 (a, b) 后面.我们用这种形 ...

  9. 01 Arduino-点亮一盏LED灯

    01 硬件连接  图片比较丑 特别说明:一般默认为二极管灯的压降是 2V 均值电流为15ma,所以如果接在5V的电源上面,串联接的电阻值为200欧姆左右,可做适当调整 切记不允许把LED灯直接并联在5 ...

  10. JS实例—DOM的增删改

    <!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8" ...