ZooKeeper Session 基本原理 - 第369篇_服务端

客户端与服务端之间的连接是基于 TCP 长连接,client 端连接 server 端默认的 2181 端口,也就是 session 会话。

从第一次连接建立开始,客户端开始会话的生命周期,客户端向服务端的ping包请求,每个会话都可以设置一个超时时间。

       本篇文章从ZK Session来对ZK有一个更深的认知。

 

Session

在Zookeeper中,Session是个很重要的概念之一,客户端与服务端之间的任何交互操作都和Session息息相关,其中包含zookeeper的临时节点的生命周期、客户端请求执行以及Watcher通知机制等。

 

Session常用属性

sessionID: 会话ID,用来唯一标识一个会话,每次客户端创建会话的时候,zookeeper 都会为其分配一个全局唯一的 sessionID。zookeeper 创建 sessionID 类 SessionTrackerImpl 中的源码。

  •  
/** * Generates an initial sessionId. High order 1 byte is serverId, next * 5 bytes are from timestamp, and low order 2 bytes are 0s. * Use ">>> 8", not ">> 8" to make sure that the high order 1 byte is entirely up to the server Id(@see ZOOKEEPER-1622). * @param id server Id * @return the Session Id */public static long initializeNextSessionId(long id) {    long nextSid;    nextSid = (Time.currentElapsedTime() << 24) >>> 8;    nextSid = nextSid | (id << 56);    if (nextSid == EphemeralType.CONTAINER_EPHEMERAL_OWNER) {        ++nextSid;  // this is an unlikely edge case, but check it just in case    }    return nextSid;}

 

Timeout:会话超时时间。客户端在构造 Zookeeper 实例时候,向服务端发送配置的超时时间,server 端会根据自己的超时时间限制最终确认会话的超时时间。

TickTime:下次会话超时时间点,默认2000 毫秒。可在 zoo.cfg 配置文件中配置,便于server 端对 session 会话实行分桶策略管理。

isClosing:该属性标记一个会话是否已经被关闭,当 server 端检测到会话已经超时失效,该会话标记为"已关闭",不再处理该会话的新请求。

 

Session的状态

下面介绍几个重要的状态:

(1)connecting:连接中,session 一旦建立,状态就是 connecting 状态,时间很短。

(2)connected:已连接,连接成功之后的状态。

(3)closed:已关闭,发生在 session 过期,一般由于网络故障客户端重连失败,服务器宕机或者客户端主动断开。

 

SessionTracker

       SessionTracker其中的一个实现类是SessionTrackerImpl:

ZooKeeper Session 基本原理 - 第369篇_服务端_02

       SessionTracker是Zookeeper中的会话管理器,负责整个zk生命周期中会话的创建、管理和清理操作:

(1)sessionsWithTimeout:这是一个ConcurrentMap<Long,Integer>类型的数据结构,用来管理会话的超时时间,这个参数会被持久化到快照文件中去。

(2)sessionsById:是一个ConcurrentHashMap<Long,SessionImpl>类型的数据结构,用于根据sessionId来管理session实体。

 

Session的创建流程

客户端和服务端Socket连接建立成功后,客户端会向服务端发送一个ConnectRequest请求,服务端接收到ConnectRequest请求后,会创建SessionImpl对象,并且把SessionImpl对象放入sessionsById中(sessionById是一个Map),并且会把Session的过期时间更新到sessionExpiryQueue中,然后会在服务端内部构造一个OpCode.createSession的Request,该Request会依次经过PrepRequestProcessor、SyncRequestProcessor、FinalRequestProcessor。

(1)在PrepRequestProcessor中设置Reqeust的txn

(2)在SyncRequestProcessor对txn进行持久化(创建session的操作会持久化)

(3)在FinalRequestProcessor会对Session进行提交,其实就是把Session的ID和Timeout存到sessionsWithTimeout中去

 

Session的刷新流程

服务端每接收到一个请求(包括增删查改和Ping请求),都会对sessionExpiryQueue中的Session的过期时间进行刷新。

 

Session的过期处理流程

 

       SessionTrackerImpl是SessionTracker的实现类,由它负责处理Session的过期时间刷新和对过期的Session进行处理。

SessionTrackerImpl是一个线程,该线程会每隔一个tickTime就去检查一下有没有Session已经过期,如果过期了,则对Session进行过期处理,构造一个closeSession的Request,交给服务端进行处理。

ZooKeeper Session 基本原理 - 第369篇_服务端_03

Session的关闭流程

       对应的操作是closeSession,也会进行持久化,同时FinalRequestProcessor在执行closeSession请求时,会删除临时节点,并且把session从sessionsById、sessionsWithTimeout、sessionExpiryQueue移除掉。