基于 nfs(net filesystem) 的 Session 共享

将共享服务器目录 mount 各服务器的本地 session 目录,session 读写受共享服务器 io 限制,不能满足高并发。

基于关系数据库的 Session 共享

这种方案普遍使用。使用关系数据库存储 session 数据,对于 mysql 数据库,建议使用 heap 引擎。这种方案性能取决于数据库的性能,在高并发下容易造成表锁(虽然可以采用行锁的存储引擎,性能会下降),并且需要自己实现 session 过期淘汰机制。

这种方案也在大型互联网中普遍使用,将用户的 session 加密序列化后以 cookie 的方式保存在网站根域名下(比如 taobao.com),当用户访问所有二级域名站点式,浏览器会传递所有匹配的根域名的 cookie 信息,这样实现了用户 cookie 化 session 的多服务共享。此方案能够节省大量服务器资源,缺点是存储的信息长度受到 http 协议限制;cookie 的信息还需要做加密解密;请求任何资源时都会将 cookie 附加到 http 头上传到服务器,占用了一定带宽。

基于 Web 容器的 Session 机制

利用容器机制,通过配置即可实现。

基于 Zookeeper 的分布式 Session 存储

基于 Redis/Memcached 的 Session 共享存储

这些 key/value 非关系存储有较高的性能,轻松达到 2000 左右的 qps,内置的过期机制正好满足 session 的自动实效特性。

六种方案罗列齐全(Redis 方案的”2000 qps”表述今天已严重低估——单实例 Redis 会话读写轻松 10 万+ qps),但选型还需要:统一评价维度、各方案的失效模式、以及”今天的答案”(Redis 集中式 vs Token 无状态的分野)。本文补全。

统一评价维度

维度 含义
性能 单次会话读写延迟与吞吐
一致性 多节点读到的会话是否即时一致
可用性 存储节点故障时会话是否丢失/服务是否中断
扩展性 应用节点水平扩容是否受限
成本 额外组件与运维投入
安全 会话数据的暴露面与防篡改

六方案评析(含失效模式)

NFS 共享目录:实现零成本;失效模式=共享 IO 单点+网络文件系统延迟抖动,高并发下全集群会话卡死。仅历史遗留。

关系数据库:持久化可靠、事务友好;失效模式=会话高频读写打满 DB 连接池(会话读写 QPS 通常是业务的数倍)、过期清理需自研定时任务、表锁/行锁竞争。仅小流量内部系统。

Cookie 化 Session:服务端零存储、天然跨子域;失效模式=4KB 容量限制、每请求带宽税、加密密钥泄露即全会话伪造、客户端可禁用 Cookie。适合”会话数据极小且需跨域共享”场景(早期淘宝系)。

Web 容器会话复制(Tomcat cluster 组播):配置即用;失效模式=全节点全量复制(N 节点 N 份副本,写放大 N 倍)、节点多时复制风暴、新节点加入全量同步慢。仅 2-3 节点小规模。

ZooKeeper 存储:强一致;但 ZK 为协调而生非为高频读写而生(写全集群同步),会话读写延迟高、且浪费协调集群容量。理论选项,实践罕见。

Redis/Memcached(今天的主流有状态方案):10 万+ qps、TTL 原生、集群横向扩展;失效模式=Redis 宕机会话丢失(主从+哨兵/Cluster 缓解)、内存成本(会话大时)、网络一跳延迟(~1ms)。Spring Session 把该方案标准化(Filter 拦截+Redis 存储+Cookie 存 sessionId)。

第七方案:无状态 Token(JWT)——范式转移

不把会话存任何地方:用户状态签名进 Token 客户端持有,服务端只验签。

  • 收益:服务端零存储零查询、天然跨域跨端、水平扩展无共享问题
  • 代价:吊销难(Token 已发出,需黑名单/短时效+refresh 轮换)、续期复杂、payload 体积大(每请求携带)、泄露后无法即时失效
  • 混合形态:access Token(短时效内存持有)+ refresh Token(HttpOnly Cookie + 服务端可吊销列表)——兼顾无状态与可控性

选型决策表

场景 方案
需要服务端即时吊销/强管控(金融/后台) Redis 集中会话(Spring Session)
多端/跨域/微服务网关统一认证 JWT(access+refresh 混合)
小规模内部系统(<3 节点) 容器复制或 DB(成本优先)
历史系统改造最小成本 Redis 方案(Filter 级接入,业务零改)
会话数据大(购物车级) 会话存 Redis + Cookie 只留 id(回归集中式)

工程细节清单(Redis 方案)

  • sessionId Cookie:HttpOnly + Secure + SameSite=Lax 三件套
  • 会话 TTL 滑动续期(每次访问重置)vs 绝对过期(安全要求高)按业务定
  • Redis 持久化策略:会话可丢则 RDB 足够;不可丢(免重登要求)则 AOF+主从
  • 灰度与迁移:双写过渡(旧 Cookie 会话 + 新 Token 并行)再切流

Session 分布式的答案十年间从”存哪里”(NFS/DB/容器/Redis)演进为”要不要存”(Token 无状态);选型的第一问不是方案对比,而是业务是否需要服务端对会话的即时控制权——需要则 Redis 集中式,不需要则 JWT 无状态,其余方案只在特殊成本约束下出场。