当前位置: 首页 > news >正文

Zookeeper(八)序列化与协议

目录

  • 一 序列化与反序列化
    • 1.1 Jute序列化工具
      • 1.1 Recor接口
      • 1.2 OutputArchive和InputArchive
  • 二 通信协议
    • 2.1 请求部分
      • 2.1.1 请求头
      • 2.2.2 请求体
      • 2.1.3 案例分析
    • 2.2 响应部分
      • 2.2.1 响应头
      • 2.2.2 响应内容
      • 2.2.3 案例分析

  • 官网:Apache ZooKeeper

一 序列化与反序列化

对于一个网络通信,首先需要解决的就是对数据的序列化和反序列化处理,在ZooKeeper中,使用了Jute这一序列化组件来进行数据的序列化和反序列化操作。

1.1 Jute序列化工具

Zookeeper的客户端与服务端之间会进行一系列的网络通信来实现数据传输,Zookeeper使用Jute组件来完成数据的序列化和反序列化操作,其用于Zookeeper进行网络数据传输和本地磁盘数据存储的序列化和反序列化工作。
实体类要使用Jute进行序列化和反序列化步骤:

  • 1.需要实现Record接口的serialize和deserialize方法;
  • 2.构建一个序列化器BinaryOutputArchive;
  • 3.序列化:调用实体类的serialize方法,将对象序列化到指定的tag中去,比如这里将对象序列化到header中;
  • 4.反序列化:调用实体类的deserialize方法,从指定的tag中反序列化出数据内容。
package com.shu.jute;import org.apache.jute.InputArchive;
import org.apache.jute.OutputArchive;
import org.apache.jute.Record;/*** @author 31380* @description MockReHeader* @create 2024/3/21 14:10*/
public class MockReHeader implements Record {private long sessionId;private String type;public MockReHeader() {}public MockReHeader(long sessionId, String type) {this.sessionId = sessionId;this.type = type;}public void setSessionId(long sessionId) {this.sessionId = sessionId;}public void setType(String type) {this.type = type;}public long getSessionId() {return sessionId;}public String getType() {return type;}public void serialize(OutputArchive outputArchive, String tag) throws java.io.IOException {outputArchive.startRecord(this, tag);outputArchive.writeLong(sessionId, "sessionId");outputArchive.writeString(type, "type");outputArchive.endRecord(this, tag);}public void deserialize(InputArchive inputArchive, String tag) throws java.io.IOException {inputArchive.startRecord(tag);this.sessionId = inputArchive.readLong("sessionId");this.type = inputArchive.readString("type");inputArchive.endRecord(tag);}@Overridepublic String toString() {return "sessionId = " + sessionId + ", type = " + type;}
}
package com.shu.jute;import org.apache.jute.BinaryInputArchive;
import org.apache.jute.BinaryOutputArchive;
import org.apache.zookeeper.server.ByteBufferInputStream;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;/*** @author 31380* @description* @create 2024/3/21 14:11*/
public class JuteTest {public static void main(String[] args) throws IOException {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();BinaryOutputArchive binaryOutputArchive = BinaryOutputArchive.getArchive(byteArrayOutputStream);new MockReHeader(0x3421eccb92a34el, "ping").serialize(binaryOutputArchive, "header");ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayOutputStream.toByteArray());ByteBufferInputStream byteBufferInputStream = new ByteBufferInputStream(byteBuffer);BinaryInputArchive binaryInputArchive = BinaryInputArchive.getArchive(byteBufferInputStream);MockReHeader mockReHeader = new MockReHeader();System.out.println(mockReHeader);mockReHeader.deserialize(binaryInputArchive, "header");System.out.println(mockReHeader);byteBufferInputStream.close();byteArrayOutputStream.close();}}

image.png

1.1 Recor接口

Zookeeper中所需要进行网络传输或是本地磁盘存储的类型定义,都实现了该接口,是Jute序列化的核心。Record定义了两个基本的方法,分别是serialize和deserialize,分别用于序列化和反序列化。其中archive是底层真正的序列化器和反序列化器,并且每个archive中可以包含对多个对象的序列化和反序列化,因此两个接口中都标记了参数tag,用于序列化器和反序列化器标识对象自己的标记。

1.2 OutputArchive和InputArchive

  • OutputArchive和InputArchive分别是Jute底层的序列化器和反序列化器定义。有BinaryOutputArchive/BinaryInputArchive、CsvOutputArchive/CsvInputArchive和XmlOutputArchive/XmlInputArchive三种实现,无论哪种实现都是基于OutputStream和InputStream进行操作。
  • BinaryOutputArchive对数据对象的序列化和反序列化,主要用于进行网络传输和本地磁盘的存储,是Zookeeper底层最主要的序列化方式。CsvOutputArchive对数据的序列化,更多的是方便数据的可视化展示,因此被用在toString方法中。XmlOutputArchive则是为了将数据对象以xml格式保存和还原,但目前在Zookeeper中基本没使用到。

注意:在最新版本的ZooKeeper中,底层依然使用了Jute这个古老的,并且似乎没有更多其他系统在使用的序列化组件。

二 通信协议

基于TCP/IP协议,ZooKeeper实现了自己的通信协议来完成客户端与服务端、服务端与服务端之间的网络通信。ZooKeeper通信协议整体上的设计非常简单,对于请求,主要包含请求头和请求体,而对于响应,则主要包含响应头和响应体
image.png

2.1 请求部分

image.png
我们将从请求头和请求体两方面分别解析ZooKeeper请求的协议设计

2.1.1 请求头

class RequestHeader {int xid;int type;}

从zookeeper.jute中可知RequestHeader包含了xid和type,xid用于记录客户端请求发起的先后序号,用来确保单个客户端请求的响应顺序,type代表请求的操作类型,如创建节点(OpCode.create)、删除节点(OpCode.delete)、获取节点数据(OpCode.getData)。

2.2.2 请求体

协议的请求体部分是指请求的主体内容部分,包含了请求的所有操作内容。

ConnectRequest:会话创建

class ConnectRequest {int protocolVersion;long lastZxidSeen;int timeOut;long sessionId;buffer passwd;}

Zookeeper客户端和服务器在创建会话时,会发送ConnectRequest请求,该请求包含协议版本号protocolVersion、最近一次接收到服务器ZXID lastZxidSeen、会话超时时间timeOut、会话标识sessionId和会话密码passwd。

GetDataRequest:获取节点数据

 class GetDataRequest {ustring path;boolean watch;
}

ZooKeeper客户端在向服务器发送获取节点数据请求的时候,会发送GetDataRequest请求,该请求体中包含了数据节点的节点路径path和是否注册Watcher的标识watch

SetDataRequest:更新节点数据

 class SetDataRequest {ustring path;buffer data;int version;
}

ZooKeeper客户端在向服务器发送更新节点数据请求的时候,会发送SetDataRequest请求,该请求体中包含了数据节点的节点路径path、数据内容data和节点数据的期望版本号version

2.1.3 案例分析

  • 发出请求获取数据

我们获取到了ZooKeeper客户端请求发出后,在TCP层数据传输的十六进制表示,其中带下划线的部分就是对应的GetDataRequest请求,即[00,00,00,1d,00,00,00,01,00,00,00,04,00,00,00,10,2f,24,37,5f,32,5f,34,2f,67,65,74,5f,64,61,74,61,01],GetDataRequest请求的完整协议定义,我们来分析下这个十六进制字节数组的含义
image.png

2.2 响应部分

获取节点数据响应的完整协议定义
image.png

2.2.1 响应头

 class ReplyHeader {int xid;long zxid;int err;}

xid与请求头中的xid一致,zxid表示Zookeeper服务器上当前最新的事务ID,err则是一个错误码,表示当请求处理过程出现异常情况时,就会在错误码中标识出来,常见的包括处理成功(Code.OK)、节点不存在(Code.NONODE)、没有权限(Code.NOAUTH)。

2.2.2 响应内容

协议的响应主体内容部分,包含了响应的所有数据,不同的响应类型请求体不同。

ConnectResponse:会话创建

 class ConnectResponse {int protocolVersion;int timeOut;long sessionId;buffer passwd;}

针对客户端的会话创建请求,服务端会返回客户端一个ConnectResponse响应,该响应体中包含了协议的版本号protocolVersion、会话的超时时间timeOut、会话标识sessionId和会话密码passwd

GetDataResponse:获取节点数据

 class GetDataResponse {buffer data;org.apache.zookeeper.data.Stat stat;
}

针对客户端的获取节点数据请求,服务端会返回客户端一个GetDataResponse响应,该响应体中包含了数据节点的数据内容data和节点状态stat

SetDataResponse:更新节点数据

 class SetDataResponse {org.apache.zookeeper.data.Stat stat;}

针对客户端的更新节点数据请求,服务端会返回客户端一个SetDataResponse响应,该响应体中包含了最新的节点状态stat

2.2.3 案例分析

我们获取到了ZooKeeper服务端响应发出之后,在TCP层数据传输的十六进制表示,其中带下划线的部分就是对应的GetDataResponse响应,即[00,00,00,63,00,00,00,05,00,00,00,00,00,00,00,04,00,00,00,00,00,00,00,0b,69,27,6d,5f,63,6f,6e,74,65,6e,74,00,00,00,00,00,00,00,04,00,00,00,00,00,00,00,04,00,00,01,43,67,bd,0e,08,00,00,01,43,67,bd,0e,08,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,0b,00,00,00,00,00,00,00,00,00,00,00,04]。
image.png
image.png

相关文章:

Zookeeper(八)序列化与协议

目录 一 序列化与反序列化1.1 Jute序列化工具1.1 Recor接口1.2 OutputArchive和InputArchive 二 通信协议2.1 请求部分2.1.1 请求头2.2.2 请求体2.1.3 案例分析 2.2 响应部分2.2.1 响应头2.2.2 响应内容2.2.3 案例分析 官网:Apache ZooKeeper 一 序列化与反序列化 …...

人工智能之Tensorflow变量作用域

在TensoFlow中有两个作用域(Scope),一个时name_scope ,另一个是variable_scope。variable_scope主要给variable_name加前缀,也可以给op_name加前缀;name_scope给op_name加前缀。 variable_scope 通过所给的名字创建或…...

ElasticSearch插件安装及配置

Docker安装ElasticSearch docker compose 安装直接看步骤三:新建索引 1、安装elasticsearch (1)下载elasticsearch和kibana docker pull elasticsearch:7.9.1 docker pull kibana:7.9.1(2)配置 mkdir -p /mydata/…...

vue+Echarts实现多设备状态甘特图

目录 1.效果图 2.代码 3.注意事项 Apache ECharts ECharts官网,可在“快速上手”处查看详细安装方法 1.效果图 可鼠标滚轮图表和拉动下方蓝色的条条调节时间细节哦 (注:最后一个设备没有数据,所以不显示任何矩形)…...

STM32使用滴答定时器实现delayms

在STM32上使用SysTick实现jiffies(时间戳)并且实现delay_ms 代码实现: volatile uint32_t jiffies 0; // 用于记录系统运行的jiffies数 void SysTick_Handler(void) {/* 每次SysTick中断,jiffies增加 */jiffies; }uint32_t tick…...

k8s的volumn解析

背景 k8s中有一套自己的存储逻辑,它和docker中的volumn类似,本文就来看一下k8s的volunm的存储设计 k8s的volumn 1.EmptyDir类型的volumn 这种类型的volumn是Pod内的容器共享的,volumn的生命周期和Pod的生命周期是一致的,不过大…...

Golang获取音视频时长信息

文章目录 一、工具简介二、使用golang获取时间长 一、工具简介 这些工具都是与多媒体处理和流媒体相关的开源工具,它们都属于 FFmpeg 多媒体框架。 FFmpeg 是一个用于处理多媒体内容(音频、视频、图像等)的命令行工具。它可以执行各种各样…...

LeetCode 面试经典150题 14.最长公共前缀

题目: 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 思路: 代码: class Solution {public String longestCommonPrefix(String[] strs) {if (strs.length 0) {return &…...

自注意力机制的理解

一、自注意力要解决什么问题 循环神经网络由于信息传递的容量以及梯度消失问题,只能建立短距离依赖关系。为了建立长距离的依赖关系,可以增加网络的层数或者使用全连接网络。但是全连接网络无法处理变长的输入序列,另外,不同的输…...

win10-误删winsock恢复方法

文件链接放在最前面 链接:https://pan.baidu.com/s/1i9X0HJJOfo63fbtOETc1Xw?pwdlfqx 提取码:lfqx 误删后应该还是可以正常连接网络的,但是重启过后直接以太网和wifi都是无法使用的。下图是我后面网络正常补充的图片 误删后是只有飞行模式…...

c#矩阵求逆

目录 一、矩阵求逆的数学方法 1、伴随矩阵法 2、初等变换法 3、分块矩阵法 4、定义法 二、矩阵求逆C#代码 1、伴随矩阵法求指定3*3阶数矩阵的逆矩阵 (1)伴随矩阵数学方法 (2)代码 (3)计算 2、对…...

array go 语言的数组 /切片

内存地址通过& package mainimport "fmt"func main() {var arr [2][3]int16fmt.Println(arr)fmt.Printf("arr的地址是: %p \n", &arr)fmt.Printf("arr[0]的地址是 %p \n", &arr[0])fmt.Printf("arr[0][0]的地址是 %p \n"…...

【Stable Diffusion】专栏介绍和文章索引(持续更新中)

目录 1 背景2 思考3 文章索引(持续更新中)3.1 入门3.2 初级3.3 中级3.3 高级 1 背景 最近开始学习AIGC,对Stable Diffusion比较感兴趣,所以新建了这个专栏,来记录自己在使用和学习Stable Diffusion的一些方法、资料以…...

RPC 快速入门

一、What 1)小故事 张三和李四都在同一个家公司负责商品交易的模块,两个人平时开发甚是紧密。 🙋🏻‍♂️ 张三:“李四,我这边一个商品下单了,但是付款数额不对,你帮我查下支付有没…...

使用Docker搭建Syslog-ng

Syslog-ng是一个可靠、多功能的日志管理系统,用于收集日志并将其转发到指定的日志分析工具。 使用Docker CLI方式搭建 步骤 1: 拉取Syslog-ng镜像 首先,需要从Docker Hub拉取Syslog-ng的官方镜像。 docker pull balabit/syslog-ng:latest步骤 2: 启动…...

使能 Linux 内核自带的 FlexCAN 驱动

一. 简介 前面一篇文章学习了 ALPHA开发板修改CAN的设备树节点信息,并加载测试过设备树文件,文件如下: ALPHA开发板修改CAN的设备树节点信息-CSDN博客 本文是学习使能 IMX6ULL的 CAN驱动,也就是通过内核配置来实现。 二. 使能…...

通过dbeaver链接dm8数据库

一、环境说明 windows 11 vmware 17 ubuntu 22 tt:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammytt:~$ docker info Client:Version: 24.0.5Context: d…...

Stable diffusion(四)

训练自己的Lora 【DataSet】【Lora trainer】【SD Lora trainer】 前置的知识 batch size:模型一次性处理几张图片。一次性多处理图片,模型能够综合捕捉多张图片的特征,最终的成品效果可能会好。但是处理多个batch size也意味着更大的显存…...

oracle 19c RAC补丁升级

1.停止集群件备份家目录 ----两节点分别操作 cd /u01/app/19.3.0/grid/bin/ crsctl stop crstar -zcvf /u01/app.tar.gz /u01/app/u01/app/19.0.0/grid/bin/crsctl start crs2.两节点 GI、DB OPatch 替换(都得执行) ----# 表示 root 用户,$…...

计算机视觉研究方向

计算机视觉是一个广泛且快速发展的领域,涵盖了多种研究方向和技术。主要的研究方向包括图像处理、目标检测与识别、图像生成、三维视觉、行为识别、深度学习与计算机视觉、多媒体分析、视频理解、风格化、全向视觉传感器等。这些研究方向和技术不断进步,…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

idea大量爆红问题解决

问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...