一个会话的生命周期是说从它创建到结束,不论它是优雅的关闭还是因为超时。要知道一个会话内发生了什么,我们先要了解会话的可能状态已经它改变状态时可能有的事件。

    大部分会话的状态字如其名:连接中(CONNECTING)、已连接(CONNECTED)、已关闭(CLOSED)和未连接(NOT_CONNECTED)。状态转化依赖于客户端和服务器间发生的不同事件。

    会话的生命周期和状态 - 图1

    图2-6 会话状态和转化

    一个会话始于未连接状态,然后转化到连接中(图2-6箭头1所示),同时初始化Zookeeper客户端。正常情况下,连接到一台Zookeeper服务器成功完成并且会话状态转化为已连接状态(箭头2)。当客户端丢失与Zookeeper服务器的连接或者不在接收到来自服务器的信息时,它的状态又转化回连接中(箭头3),然后尝试去找到另外一台Zookeeper服务器。如果它能找到另外一台服务器或者能重新与原先的服务器连接,一旦服务器确认了会话是有效的,它的状态又变为了已连接的状态。否则,会话就会过期,状态转化为已关闭(箭头4)的状态。应用能显示的关闭会话(箭头4和5)。

    有一个重要的参数你要设置的是当创建会话时的超时时间,它是Zookeeper服务允许一个会话宣称它过期的时间。如果服务在时间t内没有收到指定会话相关的消息,它就会宣称会话过期了。客户端那边,如果它在时间1\/3 t内没有收到来自服务器的消息,它会发送一个心跳消息给服务器。在2\/3 t时,客户端开始寻找另外一台服务器,它有1\/3 t的时间来找到一台。

    当尝试连接到一台不同的服务器时,非常重要的是该台服务器的Zookeeper状态至少要和客户端关注最后的Zookeeper状态一样新。如果一台服务器没有见过某个更新而客户端可能见过,那么客户端是不能连接到该台服务器的。Zookeeper决定在服务中按更新顺序来刷新。每个Zookeeper状态的变化对其他以执行的更新来说是完全顺序化的。 如果客户端在在位置i观察到了一个更新操作, 自然它 无法连接到一台服务器只见到了i’<i。在Zookeeper的实现中,有系统指派给每个更新操作的事务标识符确立了顺序。

    图2-7描述了重连事务标识符(zxids)的使用。在客户端因为超时与s1断连之后,它尝试与s2连接,但是s2的状态是滞后的,并不能反映客户端已知的变化。然而,s3看到的变化和客户端一样,它可以安全的连接。