会话与 Sa-Token
本站 sa-token-redis-jackson、分布式 session。
分布式会话:登录态为什么必须进 Redis
这一课你将能做到
- 画出「内存会话 + 多实例」的失败现场,说清为什么登录态必须集中存储
- 真实登录一次,用 redis-cli 找到 satoken: 前缀的会话 key(只读,不删),说出 Sa-Token 在 Redis 里存了什么、TTL 是多少
- 解释 timeout=86400、is-concurrent、is-share 三个配置的含义和产品效果,并演示开关关闭时会话落回内存
为什么要学
本站登录用的是 Sa-Token,默认把会话存在 JVM 内存里。开发时单实例没问题;但生产是多实例(或将来扩容、重启):
- 重启即全员下线:进程一死,内存里的登录态全没,所有用户重新登录
- 多实例登录精神分裂:Nginx 把请求轮询到 1 号实例登录,下一个请求落到 2 号实例——2 号说「你谁啊」,要求重新登录;每次请求都可能在实例间弹跳
解法只有一个:会话放到所有实例都能读的中心存储——Redis。本站生产 profile 里 codeforge.redis.enabled=true 时,sa-token-redis-jackson 自动接管会话存储。这一课让你亲眼看到它写了什么。
先建立图像
【内存会话 + 2 实例】
浏览器 ──token──▶ Nginx ──▶ 实例1(内存里有 token ✅)
│
└──▶ 实例2(内存里没有 ❌ → 401,请重新登录)
(轮询命中不同实例 → 登录态时有时无)
【Redis 会话 + 2 实例】
浏览器 ──token──▶ Nginx ──▶ 实例1 ─┐
│ ├─ 都查同一个 Redis → 结果一致 ✅
└──▶ 实例2 ───────┘
跟着做
步骤 1:读本站的 Sa-Token 配置
backend/src/main/resources/application.yml:
sa-token:
token-name: Authorization # 前端请求头名字
timeout: 86400 # 会话有效期:24 小时(秒)
is-concurrent: true # 同一账号允许多端同时登录
is-share: true # 多端登录共享同一个 token
token-style: uuid # token 样式:随机 UUID
这些配置的每个值都会变成 Redis 里的一条记录或一个 TTL——下一步亲眼验证。
步骤 2:打开开关并启动 backend
本课需要真实登录,把本机开关临时打开(Redis 已在跑):
codeforge:
redis:
enabled: true # 临时改,本课结束改回
启动 backend(IDE 或 mvnw spring-boot:run),日志确认 RedisConfig 的 Bean 生效。
步骤 3:真实登录一次
用测试账号登录(没有就先走注册接口造一个):
curl -s -X POST localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"你的账号","password":"你的密码"}'
# 返回体里有 tokenValue(token-style: uuid 的样子)
步骤 4:去 Redis 里找会话 key
docker exec -it redis-dev redis-cli
SCAN 0 MATCH satoken:* COUNT 100
你会看到类似:
satoken:login:token:<uuid> ← token → loginId 的映射
satoken:login:session:<loginId> ← 账号级会话对象