分布式 session

2023/2/17

Web 应用中将多次请求使用的上下文对象称作会话 ( Session ),单机情况下,Session 可由部署在服务器上的Web 容器(如 JBoss )管理。在使用负载均衡的集群环境中,由于负载均衡服务器可能会将请求分发到集群任何一台应用服务器上,所以保证每次请求依然能够正确的获取 Session 比单机时要复杂的多

集群环境下,Session管理主要有以下几种手段:

# Session 复制

Session 复制是早期企业应用系统使用较多的一种服务器集群 Session 管理机制。应用服务器开启 Web 容器的Session 复制功能,在集群中的几台服务器之间同步 Session 对象,使得每台服务器上都保存所有用户的 session 信息,这样任何一台服务器宕机都不会导致 Session 数据丢失,而服务器使用 Session 时,也只需要在本机获取即可

这种方案虽然简单,从本机读取 Session 信息也很快速,但只能使用在集群规模比较小的情况下。当集群规模较大时,集群服务器间需要大量的通信进行 Session 复制,占用服务器和网络的大量资源,系统不堪重负。甚至会出现服务器内存不够 Session 使用的情况

image.png

# Session 绑定

Session 绑定可以利用负载均衡的源地址 Hash 算法实现,负载均衡服务器总是将来源于同一 IP 的请求分发到同一台服务器上(也可以根据 Cookie 信息将同一用户的请求总是分发到同一台服务器上,当然这时负载均衡服务器必须工作在HTTP协议层上。这样整个会话期间,所有用户所有请求都在同一服务器上处理,即 Session 绑定在某台特定服务器上,保证 Session 总能在这台服务器上获取。这种方法又被称作会话粘滞)

image.png

但是 Session 绑定的方案显然不符合我们对系统高可用的需求,因为一旦某台服务器宕机,那么该服务器上的Session 也就不复存在了,用户请求切换到其他服务器因为没有 Session 而无法完成业务处理

早期的企业应用系统使用 C/S (客户端/服务器)架构,一种管理 Session 的方式是将 Session 记录在客户端,每次请求服务器时,将 Session 放在请求中发送给服务器,服务器处理完请求后再将修改过的 Session 响应给客户端,网站没有客户端,但是可以利用浏览器支持 Cookie 记录 Session

image.png

利用 Cookie 记录 Session 也有一些缺点,比如受 Cookie 大小限制,能记录的信息有限;每次请求响应都需要传输 Cookie,影响性能;如果用户关闭 Cookie,访问就不会正常。但是 Cookie 的简单易用,可用性高,支持应用服务器的线性伸缩,而大部分应用需要记录的 Session 信息又比较小

# Session 服务器

那么没有高可用、伸缩性好、性能也不错、对信息大小有没有限制的服务器集群 Session 管理方案呢? 答案就是 Session 服务器。利用独立部署的 Session 服务器(集群)统一管理 Session,应用服务器每次读写Session 时,都访问 Session 服务器

image.png

这种解决方案事实上是将应用服务器的状态分离,分为无状态的应用服务器和有状态的 Session 服务器,然后针对这两种服务器的不同特性分别设计其架构。对有状态的 Session 服务器,一种比较简单的方法是利用分布式缓存、数据库等,这些产品的基础上进行包装,使其符合 Session 的存储和访问要求。如果业务场景对 Session 管理有较高的要求