会话
会话(Session)是ZooKeeper中最重要的概念之一,客户端与服务端之间的任何操作都与会话息息相关,这其中就包括临时节点的生命周期、客户端请求的顺序执行以及Watcher通知机制等。
会话状态
在ZooKeeper客户端与服务端成功完成连接创建之后,就建立了一个会话。
ZooKeeper会话在整个运行期间的生命周期中,会在不同的会话状态之间进行切换。
CONNECTING | 连接中 |
CONNECTED | 已连接 |
RECONNECTING | 重新连接中 |
RECONNECTED | 已重新连接 |
CLOSE | 关闭 |
会话创建
Session是ZooKeeper中的会话实体,代表了一个客户端会话。
包含以下4个基本属性:
sessionID | 会话ID,用来标示唯一一个会话 每次客户端创建新会话的时候,ZooKeeper都会为其分配一个全局唯一的SessionID |
TimeOut | 会话超时时间。 客户端在构建ZooKeeper实例的时候,会配置一个sessionTimeOut参数用于指定会话的超时时间。 ZooKeeper客户端向服务端发送这个超时时间后,服务器会根据自己的超时时间限制最终确定会话的超时时间 |
TickTime | 下次会话超时时间点。 |
isClosing | 该属性用语标记一个会话是否已经被关闭。 |
重连
当客户端和服务端之间的网络连接断开时,ZooKeeper客户端会自动进行反复的重连,直到最终成功连接上ZooKeeper集群中的一台机器。
在这种情况下,再次连接上服务器的客户端有可能会处于以下两种状态之一:
CONNECTED:
如果在会话超时时间内重新连接上了ZooKeeper集群中的任意一台机器,那么被视为重连成功。
EXPIRED:
如果是在会话超时时间以外重新连接上的,那么服务端其实已经对该回话进行了会话清理操作,因此再次连接上的会话将被视为非法会话。
我们应该如何正确的处理CONNECTION_LOSS和SESSION_EXPIRED?
连接断开:CONNECTION_LOSS
当客户端因网络闪断与服务端断开连接,或是因为客户端当前连接的服务器出现问题导致连接断开,我们统称这类问题为"客户端与服务器连接断开"现象,即CONNECTION_LOSS。
这种情况下,ZooKeeper客户端会自动从地址列表中重新逐个选取新的地址并尝试进行重新连接,直到最终成功连上服务器。
(这里直接贴图了)
会话失效:SESSION_EXPIRED
SESSION_EXPIRED是指会话过期,通常发生在CONNECTION_LOSS(连接断开)期间。
客户端和服务器连接断开之后,由于重连接期间耗时过长,超过了会话超时时间(sessionTime)限制后还没有成功连接上服务器。
于是服务端就认为这个会话已经结束了,就会开始进行会话清理。
另一方面,客户端本身不知道会话已经失效,并且其客户端状态还是DISCONNECTED。
之后,如果客户端重新连上了服务器,那么很不幸,服务器会告诉客户端该会话已经失效(SESSION_EXPIRED)。
在这种情况下,用户就需要重新实例化一个ZooKeeper对象,继续使用。
会话转移:SESSION_MOVED
会话转移是指:客户端会话从一台服务器机器转移到了另一台服务器机器上。
如上文所说,客户端与S1服务器之间连接断开,尝试重新连接,最终成功连接上了S2服务器,并延续了有效会话,那么可以说会话从S1转移到了S2上。