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

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

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

相关文章

【开源】一个基于java语言的物联网中间件,支持常用物联网协议

项目介绍iot-ucy是使用java语言且基于netty, spring boot, redis等开源项目开发来的物联网网络中间件, 支持udp, tcp, 串口(com)通讯(window、linu...

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

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

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

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

Modbus协议很简单,结合温湿度传感器手把手教你使用Modbus协议

一、阅读温湿度传感器产品手册1、产品参数2、产品所用到的Modbus协议功能号3、产品通讯协议二、利用PC串口调试助手与温控传感器进行通信设置设置串口调试助手通讯格式字:波特率9600,校验位NONE...

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

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

HUAWEI内网最新发布了一份452页网络协议手册,GitHub一夜霸榜

前言《圣经》中有一个通天塔的故事,大致是说,上帝为了阻止人类联合起来,就让人类说不同的语言。人类没法儿沟通,达不成“协议”,通天塔的计划就失败了。但是千年以后,有一种叫“程序猿”的物种,敲着一种这个群...