首页 > Java框架应用 > Zookeeper 入门教程 > Zookeeper 的通信及会话

Zookeeper 的通信及会话

1. 前言

在前面的章节中,我们学习了 Zookeeper 的 Java 客户端 ZkClient 和 Curator 的基本使用,那这些客户端是如何与 Zookeeper 服务端建立通信的呢?我们就带着这个问题开启本节的内容。

2. Zookeeper 的通信协议

首先我们从 Zookeeper 的通信协议开始说起。我们都知道最常用的网络通信协议 TCP/IP 协议,而 Zookeeper 就是基于 TCP/IP 协议实现了自己的通信方式。
Zookeeper 的通信协议
Zookeeper 的通信协议分为两部分,请求协议和响应协议,接下来我们分别进行介绍。

2.1 请求协议

请求协议是 Zookeeper Client 向 Zookeeper Server 发送请求时所使用的协议,包含了请求头和请求体。在 Zookeeper 中使用了 RequestHeader 类作为请求头。

// RequestHeader 类实现了 Record 接口来进行序列化操作
public class RequestHeader implements Record{
    // 客户端序号,记录客户端请求发起的顺序
    private int xid;
    // 请求类型
    private int type;
}

而请求体会根据不同的请求类型来进行封装,接下来我们以会话创建、节点查询、节点更新三种类型的请求分别介绍相对应的请求体。

  • 会话创建请求
    当 Zookeeper 客户端向 Zookeeper 服务端发送会话创建的请求时,使用 ConnectRequest 类来封装请求体:

    // ConnectRequest 类实现了 Record 接口来进行序列化操作 public class ConnectRequest implements Record { // 请求协议的版本信息 private int protocolVersion; // 最后一次接收到响应的服务端 zxid private long lastZxidSeen; // 会话超时时间 private int timeOut; // 会话 id private long sessionId; // 密码 private byte[] passwd; }

  • 节点查询请求
    当 Zookeeper 客户端向 Zookeeper 服务端发送节点查询的请求时,使用 GetDataRequest 类来封装请求体:

    // GetDataRequest 类实现了 Record 接口来进行序列化操作
    

    public class GetDataRequest implements Record { // 节点全路径 private String path; // 是否对该节点开启监听 private boolean watch; }

  • 节点更新请求
    当 Zookeeper 客户端向 Zookeeper 服务端发送节点更新的请求时,使用 SetDataRequest 类来封装请求体:

    // SetDataRequest 类实现了 Record 接口来进行序列化操作
    

    public class SetDataRequest implements Record { // 节点全路径 private String path; // 节点更新的数据 private byte[] data; // 节点更新后的版本,也就是在当前版本上加 1 private int version; }

介绍了 Zookeeper 的请求协议之后,接下来我们继续学习 Zookeeper 的响应协议。

2.2 响应协议

响应协议会在接收到 Zookeeper 客户端的请求后,对请求协议进行解析并作出响应。和 Zookeeper 的请求协议相对应的,Zookeeper 的响应协议也是由响应头和响应体组成,响应体也需要根据不同的请求类型来封装响应体。在接收到 Zookeeper 客户端的请求后,由 ReplyHeader 类来解析请求头并对响应头进行封装:

// ReplyHeader 类实现了 Record 接口来进行序列化操作
public class ReplyHeader implements Record {
    // 客户端序号,记录客户端请求发起的顺序
    private int xid;
    // 事务id
    private long zxid;
    // 错误状态码
    private int err;
}
  • 会话创建响应
    当 Zookeeper 服务端接收到 Zookeeper 客户端的会话创建请求时,使用 ConnectResponse 类来封装响应体:

    // ConnectResponse 类实现了 Record 接口来进行序列化操作
    

    public class ConnectResponse implements Record { // 请求协议的版本信息 private int protocolVersion; // 会话超时时间 private int timeOut; // 会话 id private long sessionId; // 密码 private byte[] passwd; }

  • 节点查询响应
    当 Zookeeper 服务端接收到 Zookeeper 客户端的节点查询请求时,使用 GetDataResponse 类来封装响应体:

    // GetDataResponse 类实现了 Record 接口来进行序列化操作
    

    public class GetDataResponse implements Record { // 节点的数据 private byte[] data; // 节点的状态 private org.apache.zookeeper.data.Stat stat; }

  • 节点更新响应
    当 Zookeeper 服务端接收到 Zookeeper 客户端的节点更新请求时,使用 SetDataResponse 类来封装响应体:

    // SetDataResponse 类实现了 Record 接口来进行序列化操作
    

    public class SetDataResponse implements Record { // 节点的状态 private org.apache.zookeeper.data.Stat stat; }

介绍完 Zookeeper 的通信协议后,接下来我们要学习的是 Zookeeper 的会话,包括会话的结构,会话的状态等。

3. Zookeeper 的会话

Zookeeper 是一个 C/S 架构的服务,也就是 Client — Server 的形式。在我们使用 Zookeeper 时,都是使用 Zookeeper 的客户端向服务端发送请求,然后由服务端做出响应返回到客户端。在这个过程中,Zookeeper 的客户端需要与 Zookeeper 服务端建立连接,建立一个连接就是新建一个会话,那么会话的状态也就是 Zookeeper 客户端与 Zookeeper 服务端的连接状态。
接下来我们从会话的结构开始进行讲解:

3.1 Session 的结构

会话 Session 的结构包括会话ID、会话超时时间、会话关闭状态 3 个属性:
Session 的结构

  • SessionID: 会话的唯一标识,由 Zookeeper 自动分配。
  • TimeOut: 会话从新建到被关闭的时长,这个时间由 Zookeeper 服务端来管理。
  • isClosing: 会话关闭的状态,如果会话已经被关闭,该会话就不会再被使用了。

3.2 Session 的状态

在 Zookeeper 的运行过程中,会话 Session 会经历各种状态的变化,从 Zookeeper 客户端与 Zookeeper 服务端开始建立连接到连接被关闭,会话的状态会经历以下几种:

  • CONNECTING :正在连接状态,Zookeeper 客户端与 Zookeeper 服务端建立连接时的状态;
  • CONNECTIED :已连接状态,Zookeeper 客户端与 Zookeeper 服务端完成连接的状态;
  • RECONNECTING :正在重新连接状态,当 Zookeeper 客户端与 Zookeeper 服务端断开连接,Session 重连策略发起重新连接时的状态;
  • RECONNECTED :已经重新连接状态,在 RECONNECTING 的基础上,完成了 Zookeeper 客户端与 Zookeeper 服务端的重新连接;
  • CLOSE :连接关闭状态,Zookeeper 客户端与 Zookeeper 服务端断开连接的状态。

4. 总结

在本节内容中,我们学习了 Zookeeper 的通信协议的实现方式,以及 Zookeeper 会话 Session 的结构和运行中的状态变化。以下是本节内容的总结:

  1. Zookeeper 的通信协议。
  2. Zookeeper 的会话。
本文来自互联网用户投稿,不拥有所有权,该文观点仅代表作者本人,不代表本站立场。
访问者可将本网站提供的内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。
本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站,邮箱:80764001@qq.com,予以删除。
© 2023 PV138 · 站点地图 · 免责声明 · 联系我们 · 问题反馈