跳到主要内容

分布式Session

背景与需求

在分布式系统中,Session 的管理是一个重要的问题。当用户在多个服务器之间进行请求时,如何确保 Session 的一致性和可用性是关键。

在传统的单体应用中,Session 通常存储在服务器的内存中。然而,在分布式环境下,服务器 A 登录之后,请求发到服务器 B 时,服务器 B 可能不认识该用户,因为 Session 信息没有在服务器之间共享。

jwt(JSON Web Token)是一种常见的解决方案,但它也存在一些缺点,例如https://zhuanlan.zhihu.com/p/263410154中所提到的。

为了解决这个问题,需要一种共享存储的方案,使得 Session 信息能够在多个服务器之间访问。

解决方案:使用Redis存储Session

选择 Redis 的原因:Redis 是一种基于内存的 K/V 数据库,具有读写速度快的优点。由于用户信息的读取和是否登录的判断极其频繁,Redis 能够提供快速的响应。

  • MySql:虽然可以存储 Session 信息,但数据库的读写性能相对较低,可能无法满足高并发的需求。
  • 文件服务器(ceph):文件存储的方式在读取和更新 Session 信息时可能会存在一定的延迟。

种Session的时候注意范围 cookie.domain

具体实现

引入依赖:

        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置application.yml

spring:
redis:
port: 6379
host: localhost
database: 0
password: 123456

引入Spring session redis

使得自动将session存储到redis中

        <dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

修改配置:

spring:
session:
timeout: 86400
store-type: redis

测试:

允许多个实例:

image-20231021152050412

修改端口为8081

image-20231021152121076

在端口为8080的页面进行登录:

image-20231021151311737

成功加入到redis中

image-20231021151038415

此时在8081的端口查看登录信息:

image-20231021151332505

通过测试可以看出,当在 8080 端口登录后,Session 信息被成功存储到 Redis 中,并且在 8081 端口能够正确获取到登录信息,实现了 Session 的共享。

进一步分析,使用 Redis 存储 Session 的优势在于:

  1. 高性能:Redis 的内存存储和快速读写能力能够满足高并发场景下的需求,确保用户请求的快速响应。
  2. 可扩展性:Redis 可以轻松扩展,以应对不断增长的用户和请求量。
  3. 数据一致性:通过将 Session 存储在共享的 Redis 中,保证了在分布式环境下 Session 数据的一致性,避免了数据不一致导致的问题。