Springboot整合springsession实现session共享

article/2025/9/16 14:11:22

Springboot整合springsession实现session共享

简介

session我们之前有介绍过(可见springboot整合springsecurity),简单来说就是将用户信息或者数据存储在服务器上,通常用于验证用户身份或者避免通过获取相关信息。

但是,缺点也是非常明显:

  1. 占用服务器负载:我们可以使用token,用时间换取空间

  2. 对于多服务器环境,session无法共享

对于第二点缺点,我们目前有几种比较常用的解决方法

  1. 使用cookie加密的方式将session保存在客户端上

    优点是可以减轻服务器压力,缺点是每次请求都要带上cookie信息,占用一定带宽。此外若用户禁用cookie则无法使用

  2. 服务器间同步

    通过配置tomcat集群,在集群中广播自己的session信息,但是缺点很明显,当集群规模较大时,会占用大量资源来进行session同步处理

  3. 基于分布式缓存的session共享机制

    session缓存到redis中,这样不同服务器都可以直接到内存中获取session,效率高,也最常用

Springsession

springSessionspring 旗下的一个项目,把 servlet 容器实现的 httpSession替换为springSession,专注于解决session管理问题。可简单快速且无缝的集成到我们的应用中。

springsession就是spring的一个框架,实现了我们上面说的基于分布式缓存的session共享机制

操作实例

我们先来看看简单的操作实例

程序源码

pom.xml
<!--        springsession--><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId><version>2.5.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.5.1</version></dependency>
application.yml
spring:redis:#    数据库索引,默认为0database: 0#    redis host iphost: 192.168.56.129#    redis  连接端口port: 6379#    服务器连接密码(默认为空)password:#    连接超时时间(毫秒)timeout: 1000#设置springsession存储类型,默认为redissession:store-type: redis
启动类加上@EnableRedisHttpSession
@SpringBootApplication
@EnableRedisHttpSession
public class SpringsessionApplication {public static void main(String[] args) {SpringApplication.run(SpringsessionApplication.class, args);}
}
SessionController

这里我们构建一个简单的controller测试是否实现了session共享

@RestController
@RequestMapping("/session")
public class SessionController {/*** 设置session* @param request* @param attributes* @return*/@PostMapping("/set")public Map<String,Object> setSession(HttpServletRequest request, @RequestParam("attributes")String attributes){request.getSession().setAttribute("attributes",attributes);Map<String,Object> map = new HashMap<String,Object>();map.put("SessionID:",request.getSession().getId());return map;}/*** 获取session* @param request* @return*/@GetMapping("/get")public String getSession(HttpServletRequest request){String attributes = (String) request.getSession().getAttribute("attributes");return attributes;}
}

两个方法都很简单

setSession:通过请求中的参数设置session中的attributes

getSession:测试是否能获取在其他端口设定的session中对应attributes的值

运行结果

由于要体现session共享,所以我们这里将在两个不同端口运行程序

通过IDEA不同端口启用同一个项目,可以在右上角运行处选择edit config,然后添加springboot项目,并同意parallel run

port:8080 /session/set

可以看到成功设置了session并且返回了SessionID

port:8090 /session/get

成功获取到了session中的值,标明我们实现了session共享

我们再来看看redis存储的session

这里以sessionIDKEY,sessionvalue存储,但是sessionID前面的命名空间太长了,而且不具有项目标识,我们可以通过在application.yml中设置namespace="xx"即可

Springsession 逻辑分析

我们可以看到springsession使用非常简单,对于用户几乎不用进行什么操作,那么springsession具体为我们做了什么工作呢?

其实springsession通过autoconfigure帮我们自动配置了一个过滤器SessionRepositoryFitlter

SessionRepositoryFitlter
@Order(-2147483598)
public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFilter {

定义来看:

  • 这里为SessionRepositoryFilter设定了一个非常小的order值,以确保能够在filterchain中被优先执行。

    优先执行是为了将原生HttpRequest进行替换和封装

  • 继承了OncePerRequestFilter,确保一次请求只通过一次

源码命名太长,直接贴代码太乱了,这里就直接截图了

可以看到,我们这里首先对requestresponse进行封装,之后将封装请求传入doFilter()

所以具体逻辑就在两个封装类中,这里我们着重关注request的封装类

获取session的逻辑如下:

  1. this.getCurrentSession() 检查serlvet容器中是否有session,如果有session则直接返回,如果没有则去redis中去拿

  2. this.getRequestedSession() 根据请求中的信息获取sessionID,然后根据sessionIDredis中获取session

    这里并不是每次查询都是去redis中查询,而是设置了一个session缓存,每次查询先检查缓存中有没有,如果有则直接拿值,如果没有则通过httpSessionIdResolver.resolveSessionIds(this)获取sessionID

    获取sessionid有两种方式,一种是根据请求中Header信息获取,一种是放在cookie

    我们这里httpSessionIdResolver = new CookieHttpSessionIdResolver()选择使用cookie获取sessionID

    查询到session之后,更新session相关信息并返回

  3. 如果在redis中没有找到,则根据create判断是否创建新的session

基本的逻辑非常清楚也非常好理解,我们再来具体看看springsession是如何在redis中查询session

SessionRepository

springsession为我们提供了这样一个session仓库,能够完成对sessionCRUD操作

我们这里使用的是RedisSessionRepository,实现了将session存储在redis上的CRUD操作

这就是我们getRequestedSession()中使用的findById()

可以看到里面就是对redis数据库的直接操作

总结

本文主要介绍了springboot如何整合springsession实现session共享,也简单介绍了其中逻辑原理,具体的部分还是建议仔细阅读源码。

redis上的CRUD操作

[外链图片转存中…(img-guh79ZOd-1624583023491)]

这就是我们getRequestedSession()中使用的findById()

可以看到里面就是对redis数据库的直接操作

总结

本文主要介绍了springboot如何整合springsession实现session共享,也简单介绍了其中逻辑原理,具体的部分还是建议仔细阅读源码。


http://chatgpt.dhexx.cn/article/LC1ej80w.shtml

相关文章

集群产生的session共享问题

前言&#xff1a; 为了解决集群产生的session共享问题&#xff0c;我们首先需要知道以下三个概念&#xff1a; cookiesessionnginx ​ 下面将逐个分析。 Cookie 1.Cookie是什么 ​cookie的中文翻译是曲奇&#xff0c;小甜饼的意思。cookie其实就是一些数据信息&#xff0c…

Websocket Session 共享解决

Websocket Session 共享解决&#xff08;方案一&#xff09; 既然Websocket Session 不能直接序列化然后存储&#xff0c;而且如果用户请求的时候&#xff0c;开始与集群中的A 节点创建链接&#xff0c;就算把这个 Session 拿到B 节点去再给用户Push 消息&#xff0c;应该也…

使用redis实现session共享

继上一遍文章&#xff0c;使用nginx实现负载均衡以后&#xff0c;新的问题又产生了&#xff0c;当使用负载均衡以后&#xff0c;我们如何实现session共享&#xff0c;因为session是保存在服务端的&#xff0c;对于单体应用来说这不是问题&#xff0c;因为只有一个服务器&#x…

Session共享问题-session原理

问题1&#xff1a;微服务情况下。域名不同。session不共享 问题2&#xff1a;分布式系统下。同一个域名下&#xff0c;多个服务。session会出现不同步问题&#xff08;例如第一次访问的是A服务&#xff0c;保存了。第二次访问了B,查询到的还是没信息&#xff09; 解决&#xf…

Springboot:Session共享

1、概述 传统单机web应用中&#xff0c;一般使用tomcat/jetty等web容器时&#xff0c;用户的session都是由容器管理。浏览器使用cookie中记录sessionId&#xff0c;容器根据sessionId判断用户是否存在会话session。这里的限制是&#xff0c;session存储在web容器中&#xff0c…

Java -- SpringSession实现session共享

在集群系统中&#xff0c;经常需要将 Session 进行共享。不然会出问题&#xff1a;用户在系统A上登陆以后&#xff0c;假如后续的一些操作被负载均衡到系统B上面&#xff0c;系统B发现本机上没有这个用户的 Session &#xff0c;会强制让用户重新登陆。 如在同域名&#xff0c…

shiro分布式session共享

当我们开发的程序需要跑在多个tomcat容器或者多台机器上时&#xff0c;shiro的默认session存储就不能满足我们的需求了&#xff0c;其中shiro默认的session是存储在运行jvm内存中的&#xff0c;使用的AbstractSessionDAO抽象类的一个子类MemorySessionDAO&#xff0c;当我们需要…

tomcat+redis实现session共享

注意&#xff1a;在实际应用中&#xff0c;发现该方案会不定期导致Tomcat假死&#xff08;怀疑Redis连接未释放&#xff09;&#xff0c;慎用。 服务器192.168.14.132和192.168.14.133&#xff0c; 均已经安装tomcat&#xff0c;tomcat安装过程不再赘述。 采用192.168.14.132…

Session共享问题

Session共享及Session保持或者叫做Session⼀致性 1、Session问题原因分析 出现这个问题的原因&#xff0c;从根本上来说是因为Http协议是无状态的协议。客户端和服务端在某次会话中产生的数据不会被保留下来&#xff0c;所以第⼆次请求服务端无法认识到你曾经来过&#xff0c;…

session共享(redis实现)

引言 大厂很多项目都是部署到多台服务器上&#xff0c;这些服务器在各个地区都存在&#xff0c;当我们访问服务时虽然执行的是同一个服务&#xff0c;但是可能是不同服务器运行的&#xff1b; 在我学习项目时遇到这样一个登录情景&#xff0c;假设有如下三台服务器&#xff0…

如何实现session共享的几种解决方案?

先了解一下为什么会出现这种session共享的解决方案&#xff1f; 随着互联网公司的项目在微服务和分布式的环境下进行的搭建&#xff0c;导致一个项目可能分别部署在几个甚至很多的服务器集群下&#xff0c;此时就会出现一个问题当用户进行一个session会话的时候&#xff0c;比…

session共享几种方式

Session共享三种方式 1.nginx基于ip_hash负载均衡。 只需要更改nginx.conf配置文件。添加ip_hash就可以了。 缺点&#xff1a;1.由于ip_hash分配tomcat的时候用的是除法&#xff0c;所以新添加一台服务器会导致分配不到原来程序上&#xff0c;session会丢失。2.同一个公网ip…

session共享学习

一、Session共享 1 什么是Session共享    是指在一个浏览器对应多个Web服务时&#xff0c;服务端的Session数据需要共享。 2 Session共享应用场景 单点登录Web服务器集群等 3 Session共享常见的解决方案 3.1 Session复制       通过对应用服务器的配置开启服务器的Sess…

redis实现session共享

session共享 什么是session&#xff1f; 由于 HTTP 协议是无状态的协议&#xff0c;所以服务端需要记录用户的状态时&#xff0c;就需要用某种机制来识具体的用户。Session 是另一种记录客户状态的机制&#xff0c;不同的是 Cookie 保存在客户端浏览器中&#xff0c;而 Sessi…

UART协议概述与实现

UART协议概述&#xff08;一&#xff09; 协议描述关键代码逻辑写在最后 协议描述 常见的三大低速通信协议之一&#xff0c;UART&#xff0c;通用异步收发协议。非常简单的协议&#xff0c;协议细节不需要多说&#xff0c;只说需要注意的点。空闲位为高位&#xff0c;起始位为…

UART协议简述及编程

UART原理简述 通用异步收发器简称UART&#xff08;universal asynchronous receiver transmitter&#xff09;。他的用途很广泛&#xff0c;一般常用的就是用来输出打印的信息&#xff0c;也可以外接各种模块&#xff0c;例如GPS和蓝牙等。 正是因为这种协议非常的简单可靠&…

UART协议及串口回环

UART协议及串口回环 一、异步通信的分类1、UART&#xff08;通用异步收发器&#xff09;2、RS4223、RS4854、Modbus5、接口标准 二、UART协议要求1、空闲状态2、起始位3、数据位4、校验位5、停止位6、波特率7、比特率 三、汉字发送四、串口回环uart_txuart_rxctrltop 五、参考六…

基于verilog的uart协议实现

目录 1、理论介绍 2、架构设计 3、代码设计 一、发送模块代码 二、接收代码设计 三、顶层模块设计 四、测试代码 4、仿真实验 1、理论介绍 uart&#xff1a;通用异步收发传输器&#xff08;Universal Asynchronous Receiver/Transmitter)&#xff0c;是一种串行的收发方式…

UART协议快速扫盲(图文并茂+超详细)

文章目录 1 UART发展历史1.1 早期的串行通讯设备1.2 早期的芯片级UART1.3 现代UART的发展 2 预备知识3 协议层起始位数据校验位停止位波特率 4 传输过程5 物理层6 优缺点 1 UART发展历史 1.1 早期的串行通讯设备 早期的电报机器使用长度可变的脉冲信号进行数据传输&#xff0…

UART协议学习

通信协议分层 物理层 物理层规定通讯系统具有的机械、电子功能部分的特性&#xff0c;确保原始数据在物理媒体的传输。如RS232、RS485等就是电气协议&#xff0c;规定了数据传输时的电平标准&#xff0c;网络上许多博主将UART看作一个协议族&#xff0c;这些电气协议都是UART…