session的概念
- client与server只建立一个session。session失效后,再次建立session。session不失效就一直用这个session。
- 之后的任何请求,都关联这个session。
- session过期后,会删除该session创建的所有临时节点。
作用
- 临时节点的是生命周期
- watcher通知机制
- 与server通信的媒介
session本质上就是:一个tcp长连接。session标识了这个长连接。
在server看来,一个session就代表了一个client。
session存哪
- client会存。每次请求依赖这个session。
- server会存。并对这个session进行管理。session失效的判断,是由server决策的。
session的数据结构
属性 | 描述 |
---|---|
sessionID | 会话ID,唯一标识一个session,每次创建session的时候生成,全局唯一。生成策略:时间戳和机器ID,这二者的一系列位操作与操作,生成,保证唯一 |
TimeOut | 会话超时时间。客户端在创建session时定义。server会根据这个时间判断是否过期 |
TickTime | 下次会话超时时间。server在进行session定期扫描和管理的时候使用。约等于 当前时间+超时时间 |
isClosing | 记录session是否已经被关闭。关闭后,收到该session的请求,直接不处理了 |
session激活
session的管理在server端。由sessionTracker负责。管理方式就是传说中的“分桶策略”。
session以时间戳为桶进行存储。横坐标就是时间戳。
每个session的 ExpirationTime 的计算公式
ExpirationTime_ = currentTime + SessionTimeout
ExpirationTime = (ExpirationTime_/ExpirationInterval + 1) * ExpirationInterval
ExpirationInterval就是session的tickTime的值。默认2000毫秒。
接着看上图,激活的过程,其实就是session在横坐标移动的过程。
激活的触发条件
- 只要client向server发送请求(包括读写请求),就会触发一次会话激活。
- 如果client发现在sessionTimeout / 3 时间内尚未向server发送任何请求,那么client就会主动发起一个ping请求。server收到client的ping请求后,触发激活。
激活的执行动作
- 检查会话是否已经被关闭。已经被关闭,不再继续执行。
- 计算该session新的超时时间ExpirationTime。
- 定位该会话超时时间的横坐标
- session迁移。session迁移就是把session存放的地方,从当前横坐标移动到新的横坐标中。
session保持连接
- client:创建会话,指定超时时间timeout
- client:经过t/3时间,未收到server的任何响应(a.自己没有请求server。b.请求了,server挂了)。则主动向server发送ping心跳。
- client:经过2t/3时间,未收到server的任何响应,会尝试连接其他server节点。
- server:经过t时间,没有收到client的任何请求,server判定session过期。这个经过t时间,不是起定时任务监控这个t时间,是server一直扫横坐标。
client重连其他server,要保证新的server能看到新的最新事务 >= 之前server看到的最新事务。所以client连接到新的server后,会先判断最新事务的zxid是否满足 client上记录的zxid <= server上最新的zxid。若不符合,则尝试连接到另一个server。
session清理
server会扫描“分桶策略”的横坐标。在当前时间之前的桶中的session,都是过期的session。未过期的session都已经激活到后面的时间中了。
在会话分桶策略中,zk将ExpirationInterval的倍数作为时间点来分布会话,因此,超时时间线程只要在这些指定的时间上进行检查即可,这样既提高了会话检查的效率,而且由于是批量清理,性能也非常好。
这就是“分桶策略”的优势,判断超时,并不是一个session一个session的扫。而是通过timeout让session不断的迁移,到超时时间未迁移的session,就是超时的session。
清理的过程
标记会话状态为“已关闭”
session属性中isClosing属性标记为true发起“会话关闭”请求
session的关闭是client来做的。server通知client,把session关闭。收集该session的临时节点
添加“节点删除”事务变更
将session从server中移除
关闭nio。tcp长连接。