面试知识库
基础

分布式Session方案#

一句话答案#

推荐 Redis 集中存储 Session(简单高效),也可用 JWT Token(无状态但无法主动失效)。

核心要点

问题背景: 负载均衡下,同一客户端的多次请求可能被分发到不同服务器,服务器之间需要共享 Session 才能正确处理请求。

四种方案对比:

方案原理优点缺点
粘性 Session(Sticky Session)负载均衡器对源 IP 做哈希,同一 IP 始终路由到同一服务器实现简单,无需改代码服务器宕机则该 IP 用户 Session 全部丢失;负载不均衡
Session 复制/同步集群内通过广播同步 Session 数据,每台服务器都有全量 SessionSession 不丢失,任意节点可处理请求同步开销大,集群规模受限;内存占用翻倍增长
集中式存储(推荐)用 Redis / 数据库集中存储 Session,所有服务器读写同一存储扩展性好,服务器无状态;Session 不随服务器宕机丢失依赖外部存储的可用性;增加一次网络 IO
客户端存储将 Session 数据存在 Cookie 中(或使用 JWT),客户端每次请求自带服务端完全无状态,扩展性最好Cookie 大小限制(4KB);安全性低(数据在客户端);无法服务端主动失效

方案一:粘性 Session(Sticky Session)

实现:Nginx 的 ip_hash 指令

upstream backend {
    ip_hash;       # 同一 IP 固定路由到同一后端
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

问题:
  ① 服务器宕机 → 该服务器上的所有 Session 丢失
  ② 某些 IP 段请求量大 → 负载不均
  ③ 客户端使用代理时,大量用户共享同一 IP → 热点问题
plaintext

方案二:Session 复制

实现:Tomcat 集群的 DeltaManager 广播同步

问题:
  每新增一个 Session → 广播到 N-1 台机器 → O(N^2) 通信量
  适合小集群(3~5 台),大规模集群不可用
plaintext

方案三:Redis 集中存储(推荐)

方案四:JWT 无状态方案

流程:
  1. 用户登录 → 服务端生成 JWT Token(包含用户 ID、角色、过期时间等)
  2. 返回 Token 给客户端(存 Cookie / LocalStorage)
  3. 客户端每次请求携带 Token(Header: Authorization: Bearer xxx)
  4. 服务端验证 Token 签名 → 提取用户信息 → 无需查 Session

优势:完全无状态,服务端不存储任何东西
劣势:Token 无法主动失效(除非引入黑名单机制,又回到有状态)
plaintext

推荐方案:Redis 集中存储 + JWT 结合

JWT 存放轻量信息(用户 ID、角色),用于鉴权
需要存储的会话数据(购物车、用户偏好等)放 Redis
兼顾无状态的可扩展性和服务端数据管理的灵活性
plaintext
面试回答(2分钟版)

分布式环境下负载均衡会把同一用户的请求分发到不同服务器,如果 Session 存在单台服务器上就会出现会话丢失。常见有四种方案:第一是粘性 Session,通过 Nginx 的 ip_hash 让同一 IP 始终路由到同一台机器,简单但服务器宕机则该用户 Session 全丢。第二是 Session 复制,集群内广播同步所有 Session 数据,但同步开销是 O(N^2),只适合小集群。第三是 Redis 集中存储,这是最推荐的方案,用 Spring Session + Redis 把所有 Session 统一存到 Redis,服务器完全无状态可以随意水平扩展,Session 也不会因某台机器宕机而丢失。第四是 JWT 无状态方案,服务端签发 Token 客户端每次请求自带,完全无状态但 Token 无法主动失效。最佳实践是两者结合:JWT 存放轻量的身份信息用于鉴权,需要管理的会话数据如购物车、偏好等放 Redis,兼顾无状态的扩展性和服务端数据管理的灵活性。

追问与易错

追问方向:

  • “JWT 怎么让 Token 失效?”→ JWT 本身无法主动失效(无状态),变通方案:短过期时间(如 15 分钟)+ Redis 维护黑名单(注销时将 Token 加入黑名单直到过期)
  • “Redis Session 挂了怎么办?”→ Redis 部署主从 + Sentinel 哨兵保证高可用,或用 Redis Cluster;极端情况 Redis 全挂则降级为 JWT 无状态模式
  • “JWT Token 太大影响性能吗?”→ 会,JWT 包含 Header+Payload+Signature 通常 300~500 字节,每次请求都携带增加带宽开销,应只存必要信息(用户 ID、角色)不存大量业务数据

易错点:

  • ❌ JWT 就是安全的——不做加密不应放敏感信息
  • ❌ Redis Session 和 JWT 选一个——可以结合