分布式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
测试:
允许多个实例:
修改端口为8081
在端口为8080的页面进行登录:
成功加入到redis中
此时在8081的端口查看登录信息:
通过测试可以看出,当在 8080 端口登录后,Session 信息被成功存储到 Redis 中,并且在 8081 端口能够正确获取到登录信息,实现了 Session 的共享。
进一步分析,使用 Redis 存储 Session 的优势在于:
- 高性能:Redis 的内存存储和快速读写能力能够满足高并发场景下的需求,确保用户请求的快速响应。
- 可扩展性:Redis 可以轻松扩展,以应对不断增长的用户和请求量。
- 数据一致性:通过将 Session 存储在共享的 Redis 中,保证了在分布式环境下 Session 数据的一致性,避免了数据不一致导致的问题。