Zookeeper 的通信及会话(zookeeper通俗)

createh52个月前 (02-01)技术教程12

1. 前言

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

2. Zookeeper 的通信协议

首先我们从 Zookeeper 的通信协议开始说起。我们都知道最常用的网络通信协议 TCP/IP 协议,而 Zookeeper 就是基于 TCP/IP 协议实现了自己的通信方式。


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; } 代码块1234567
  • 节点更新请求
    当 Zookeeper 客户端向 Zookeeper 服务端发送节点更新的请求时,使用 SetDataRequest 类来封装请求体:
    // SetDataRequest 类实现了 Record 接口来进行序列化操作 public class SetDataRequest implements Record { // 节点全路径 private String path; // 节点更新的数据 private byte[] data; // 节点更新后的版本,也就是在当前版本上加 1 private int version; } 代码块123456789

介绍了 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; } 代码块1234567891011
  • 节点查询响应
    当 Zookeeper 服务端接收到 Zookeeper 客户端的节点查询请求时,使用 GetDataResponse 类来封装响应体:
    // GetDataResponse 类实现了 Record 接口来进行序列化操作 public class GetDataResponse implements Record { // 节点的数据 private byte[] data; // 节点的状态 private org.apache.zookeeper.data.Stat stat; } 代码块1234567
  • 节点更新响应
    当 Zookeeper 服务端接收到 Zookeeper 客户端的节点更新请求时,使用 SetDataResponse 类来封装响应体:
    // SetDataResponse 类实现了 Record 接口来进行序列化操作 public class SetDataResponse implements Record { // 节点的状态 private org.apache.zookeeper.data.Stat stat; } 代码块12345

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

3. Zookeeper 的会话

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

3.1 Session 的结构

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

  • 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 的会话。

相关文章

MQTT协议介绍及Java教程(mqtt协议运行在哪一层)

一、 概述  MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅模式的"轻量级"通讯协议,它和 Modbus TCP 一样都...

Java 泛型使用(类、方法、接口协议、类型通配符、通配符上下限)

一、简介泛型:是 JDK5 中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。一提到参数,最熟悉的就是定...

分布式协议与算法,你了解多少?(分布式协议 paxos)

我这里将主要列举一致性Hash算法、Gossip协议、QuorumNWR算法、PBFT算法、PoW算法、ZAB协议,Paxos会分开单独讲。一致性Hash算法一致性Hash算法是为了解决Hash算法的...

ThingsBoard物联网平台实践 LoRa协议+node-red+mqtt 实现单灯控制

ThingsBoard是一个基于Java的开源物联网平台,可实现物联网项目的快速开发,管理和扩展。ThingsBoard 使用行业标准物联网协议(MQTT,CoAP和HTTP)实现设备连接,并支持云和...

6 张图带你彻底搞懂分布式事务 XA 模式

XA 协议是由 X/Open 组织提出的分布式事务处理规范,主要定义了事务管理器 TM 和局部资源管理器 RM 之间的接口。目前主流的数据库,比如 oracle、DB2 都是支持 XA 协议的。mys...

实战Netty!基于私有协议,怎样快速开发网络通信服务

私有协议编写目的本文档用于描述边缘计算单元(以下简称边缘盒)与上位机配置软件(以下简称上位机)之间进行的数据交互通信协议。通信方式边缘盒作为服务端,上位机作为客户端,采用TCP/IP协议的socket...