Session 共享

什么是 Session

由于 HTTP 协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户。Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是 Session。客户端浏览器再次访问时只需要从该 Session 中查找该客户的状态就可以了。

为什么需要 Session 共享

在互联网行业中用户量访问巨大,往往需要多个节点共同对外提供某一种服务,如下图:

 

shiro redis 缓存共享 redis的session共享_session共享

用户的请求首先会到达前置网关,前置网关根据路由策略将请求分发到后端的服务器,这就会出现第一次的请求会交给服务器 A 处理,下次的请求可能会是服务B处理,如果不做 Session 共享的话,就有可能出现用户在服务 A 登录了,下次请求的时候到达服务 B 又要求用户重新登录。

前置网关一般使用 lvs、Nginx 或者 F5 等软硬件,有些软件可以指定策略让用户每次请求都分发到同一台服务器中,这也有个弊端,如果当其中一台服务 Down 掉之后,就会出现一批用户交易失效。在实际工作中建议使用外部的缓存设备来共享 Session,避免单个节点挂掉而影响服务,使用外部缓存 Session 后,我们的共享数据都会放到外部缓存容器中,服务本身就会变成无状态的服务,可以随意的根据流量的大小增加或者减少负载的设备。

一般 Tomcat 有自带的 Session 共享功能,但是使用起来并不是很便利,官方也不推荐大规模的使用,最常见的方式就是使用 Redis 来实现后端服务的 Session 共享。

Spring Session

Spring Session 提供了一套创建和管理 Servlet HttpSession 的方案。Spring Session 提供了集群 Session(Clustered Sessions)功能,默认采用外置的 Redis 来存储 Session 数据,以此来解决 Session 共享的问题。

Spring Session 为企业级 Java 应用的 session 管理带来了革新,使得以下的功能更加容易实现:

  • API 和用于管理用户会话的实现。
  • HttpSession - 允许以应用程序容器(即 Tomcat)中性的方式替换 HttpSession。
  • 将 session 所保存的状态卸载到特定的外部 session 存储中,如 Redis 或 Apache Geode 中,它们能够以独立于应用服务器的方式提供高质量的集群。
  • 支持每个浏览器上使用多个 session,从而能够很容易地构建更加丰富的终端用户体验。
  • 控制 session id 如何在客户端和服务器之间进行交换,这样的话就能很容易地编写 Restful API,因为它可以从 HTTP 头信息中获取 session id,而不必再依赖于 cookie。
  • 当用户使用 WebSocket 发送请求的时候,能够保持 HttpSession 处于活跃状态。

需要说明的很重要的一点就是,Spring Session 的核心项目并不依赖于 Spring 框架,所以,我们甚至能够将其应用于不使用 Spring 框架的项目中。