无状态服务
Session 外置、十二要素;对照 spring-cloud。
30 分钟
无状态服务
水平扩展的前提是:任意实例都能处理任意请求,不依赖本地内存里的 Session 或临时文件。无状态化是单体走向 spring-cloud-essentials 微集群的第一步,也是 building-for-scale 的关键实践。
学习目标
- 定义「有状态」与「无状态」在 HTTP 服务中的具体表现
- 设计 Session 外置方案(Redis、JWT、Sticky Session 对比)
- 对照十二要素(12-Factor)中与进程、配置相关的条目
核心概念
有状态服务 把用户上下文存在本机:Session Map、上传临时文件、内存计数器。扩容后新实例没有这份数据,必须 会话粘滞(Sticky Session),故障时 Session 丢失。
无状态服务 把状态外置:
| 状态类型 | 外置方案 | 注意点 |
|---|---|---|
| 登录 Session | Redis / JWT | JWT 难主动失效;Redis 需高可用 |
| 文件上传 | 对象存储(S3/OSS) | 不要写本地 /tmp |
| 配置 | 环境变量 / 配置中心 | 见 spring-cloud Config |
| 幂等键 | DB / Redis | 防重复提交 |
// 反模式:static Map 存 Session
private static Map<String, User> sessions = new HashMap<>();
// 正模式:sessionId → Redis,任意 Pod 可读
redis.get("session:" + sessionId);
Spring Boot 中 spring.session.store-type=redis 是常见起点;网关层鉴权后可透传 X-User-Id,业务服务不再碰 Session。
与微服务
无状态 + 服务注册发现 → 随意扩缩容。配合 nginx-essentials 做七层路由,配合 scale-load 理解负载均衡策略。
练习
- 审计一个现有 Controller:是否依赖
HttpSession或静态变量? - 画出 Session 外置后的请求链路(客户端 → 网关 → App × N → Redis)
- 对比 Sticky Session 与 Redis Session 在节点宕机时的用户体验
小结
无状态 = 实例可替换;状态进 Redis/DB/对象存储,扩容才不需要猜哪台机器握着你用户的 Session。
加载本节练习…