讲一下 session
主题
讲一下 session
为什么有 session
原因是 HTTP1.0/1.1 协议是无状态的,无法知道谁是谁。服务端又有记录一些个性化数据的需求,就产生了 session。对应的,在客户端存在 Cookie 也是基于此理由。
session 是怎么管理的
实际上,Servlet 第一时间不会产生 session,只有当第一次访问 HttpSession 时,才会真正意义上为这个请求分配 session。这个是由 SessionManager 管理的,本质上是一个 key-value 结构,session id 为 key,session 对象为值。
响应返回客户端时,会将 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,有就直接使用,没有就继续查 Redis。Redis 内查到,就根据 Redis 记录重新构建 session。
优点:
性能比数据库方案好。灵活性高,可进一步优化。
缺点:
需要自定义 SessionManager,需要熟悉相关 API。
小结
Session 在开发中还是必须品。为提升客户体验,我们都应该慢慢支持会话共享。选择合适的会话共享方案,更好提升客户满意度。