讲一下 session

主题

讲一下 session

为什么有 session

原因是 HTTP1.0/1.1 协议是无状态的,无法知道谁是谁。服务端又有记录一些个性化数据的需求,就产生了 session。对应的,在客户端存在 Cookie 也是基于此理由。

session 是怎么管理的

实际上,Servlet 第一时间不会产生 session,只有当第一次访问 HttpSession 时,才会真正意义上为这个请求分配 session。这个是由 SessionManager 管理的,本质上是一个 key-value 结构,session idkeysession 对象为值。

响应返回客户端时,会将 session id 写入 Cookie Header 中,这是协议约定的一个 Header。只要客户端再发起请求时能带上这个 session id,就能再找回 session,维持状态。

集群间 session 如何共享

方案1

session sticky,所谓的会话绑定。就是一旦会话在某机器上生成,就设置规则,以后的请求,就一直在这台机器上处理。

优点

简单,程序不需要做过多改变。

缺点

如果当前机器挂了,客户 session 就丢失了。再请求过来,就需要重新登录创建 session

方案2

数据库存储。一台机器将 session 创建后,就存入数据库。任意一台机器后续接到请求后,基于 session id 先查自己的 SessionManager,有就直接使用,没有就继续查数据库。数据库内查到,就根据数据库记录重新构建 session

优点

简单,程序不需要做过多改变。

缺点

由于接入数据库,所以速度上会比方案1慢。

方案3

机器间广播数据。一台机器将 session 创建或更新后,就广播数据。任意一台机器接到广播后,基于广播数据构建 session 或更新 session 内数据。

优点

简单,程序不需要做过多改变。

缺点

由于广播的需要,所以集群间的数据流动相当频繁。节点多的情况下,数据传输压力较大。

方案4

以上两种方案,都是 WAS 提供的集群共享会话方案。本方案不能通过配置,需要编码实现。

将会话存于 Redis。一台机器将 session 创建后,就存入 Redis。任意一台机器后续接到请求后,基于 session id 先查自己的 SessionManager,有就直接使用,没有就继续查 RedisRedis 内查到,就根据 Redis 记录重新构建 session

优点

性能比数据库方案好。灵活性高,可进一步优化。

缺点

需要自定义 SessionManager,需要熟悉相关 API

小结

Session 在开发中还是必须品。为提升客户体验,我们都应该慢慢支持会话共享。选择合适的会话共享方案,更好提升客户满意度。