详解 Spring Session 架构与设计

本文深入探讨了Spring Session在Web开发中的重要性,解释了HTTP无状态特性以及Cookie和Session的使用场景。Spring Session通过Session和SessionRepository组件提供了灵活的Session管理,支持多种存储方式,如Redis。文章详细介绍了RedisSession和RedisOperationsSessionRepository的实现,并展示了Session在Redis中的存储结构。此外,还讲解了Spring Session如何通过定时任务和Expiration Key机制来处理Session的失效。最后,阐述了Spring Session与Web集成的关键组件和工作流程。
摘要由CSDN通过智能技术生成

前言
开始进行 Web 开发时,您可能在使用 Session 时会碰到 Cookie 和 LocalStorage,被它们所干扰。因为他们都可以存储数据,有过期时间,不需要在使用时重新请求。您还会遇到这样的情况,Web 容器(例如 Tomcat、Jetty)包含 Session 的实现,当服务器重启之后,之前的登录状态会失效需要重新登录。

为什么需要 Spring Session

HTTP 协议

我们先从 HTTP 协议说起。HTTP 协议有个特点,是无状态的,意味着请求与请求是没有关系的。早期的 HTTP 协议只是用来简单地浏览网页,没有其他需求,因此请求与请求之间不需要关联。但现代的 Web 应用功能非常丰富,可以网上购物、支付、游戏、听音乐等等。如果请求与请求之间没有关联,就会出现一个很尴尬的问题:Web 应用不知道您是谁。例如,用户登录之后在购物车中添加了三件商品到购物车,刷新一下网页,用户仍然处于未登录的状态,购物车里空空如也。很显然这种情况是不可接受的。为此 HTTP 协议急需一种技术让请求与请求之间建立起联系来标识用户。于是出现了 Cookie 技术。

Cookie 技术

Cookie 是 HTTP 报文的一个请求头,Web 应用可以将用户的标识信息或者其他一些信息(用户名等等)存储在 Cookie 中。用户经过验证之后,每次 HTTP 请求报文中都包含 Cookie;当然服务端为了标识用户,即使不经过登录验证,也可以存放一个唯一的字符串用来标识用户。采用 Cookie 就解决了用户标识的问题,同时 Cookie 中包含有用户的其他信息。Cookie 本质上就是一份存储在用户本地的文件,里面包含了需要在每次请求中传递的信息。但 Cookie 存在以下缺点:

Cookie 具有时效性,超过过期时间就会失效。

服务提供商利用 cookie 恶意搜集用户信息,例如用户在未登录的情况下去商城浏览了商品,商城就会把广告公司的 Cookie 加入到用户的浏览器中,每当用户浏览和广告公司合作的网站时,都会看到之前在商城浏览过的类似商品。

每次 Cookie 都会把除用户标识之外的其他用户信息也在 Cookie 中传递,增加了请求的流量开销。

Session 技术

Cookie 以明文的方式存储了用户信息,造成了非常大的安全隐患,而 Session 的出现解决这个问题。用户信息可以以 Session 的形式存储在后端。这样当用户请求到来时,请求可以和 Session 对应起来,当后端处理请求时,可以从 Session 中获取用户信息。那么 Session 是怎么和请求对应起来的?答案是通过 Cookie,在 Cookie 中填充一个类似 SessionID 之类的字段用来标识请求。这样用户的信息存在后端,相对安全,也不需要在 Cookie 中存储大量信息浪费流量。但前端想要获取用户信息,例如昵称,头像等信息,依然需要请求后端接口去获取这些信息。

Session 管理

通过 Cookie、Session 这些技术,服务端可以标识到不同的用户,从而提供一些个性化服务。随着用户规模的增长,一个应用有多个实例,部署在不同的 Web 容器中。因此应用不可能再依赖单一的 Web 容器来管理 Session,需要将 Session 管理拆分出来。为了实现 Session 管理,需要实现以下两点:

Session 管理需要接入高可用,高性能的存储组件。

有一种可靠的失效机制,当 Session 过期时,将 Session 失效掉。

为此常见的 Session 管理都会采用高性能的存储方式来存储 Session,例如 Redis 和 MemCache,并且通过集群的部署,防止单点故障,提升高可用性。然后采用定时器,或者后台轮询的方式在 Session 过期时将 Session 失效掉。

Spring Session 应运而生,它是一种流行的 Session 管理实现方式,相比上文提到的,Spring Session 做的要更多。Spring Session 并不和特定的协议如 HTTP 绑定,实现了一种广义上的 Session,支持 WebSocket 和 WebSession 以及多种存储类型如 Redis、MongoDB 等等。

Spring Session 架构设计
Spring Session 由核心模块和具体存储方式相关联的实现模块构成。核心模块包含了 Spring Session 的基本抽象和 API。Spring Session 有两个核心组件:Session 和 SessionRepository。Spring Session 简单易用,通过 SessionRepository 来操作 Session。当建立会话时,创建 Session,将一些用户信息(例如用户 ID)存到 Session 中,并通过 SessionRepository 将 Session 持久化。当会话重新建立的时候,可以获取到 Session 中的信息。同时后台维护了一个定时任务,通过一些巧妙的方式,将过期的 Session 通过 SessionRepository 删除掉。下面详细介绍一下这两个核心组件。

Session

Session 即会话,这里的 Session 指的是广义的 Session 并不和特定的协议如 HTTP 绑定,支持 HttpSession、WebSocket Session,以及其他与 Web 无关的 Session。Session 可以存储与用户相关的信息或者其他信息,通过维护一个键值对(Key-Value)来存储这些信息。Session 接口签名如清单 1 所示:

清单 1. Session 接口
public interface Session {
String getId();
<T> T getAttribute(String attributeName);
Set<String> getAttributeNames();
void setAttribute(String attributeName, Object attributeValue);
void removeAttribute(String attributeName);
}

以下是相关参数介绍:

getId:每个 Session 都有一个唯一的字符串用来标识 Session。

getAttribute:获取 Session 中的数据,需要传递一个 name 获取对应的存储数据,返回类型是泛型,不需要进行强制转换。

getAttributeNames:获取 Session 中存储信息所有的 name(也就是 Key)。

setAttribute:填充或修改 Session 中存储的数据。

<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值