一、Jute

  Jute是Zookeeper底层序列化组件,其用于Zookeeper进行网络数据传输和本地磁盘数据存储的序列化和反序列化工作。

  2.1 Jute序列化  

  MockReHeader实体类

package com.hust.grid.leesf.jute.examples;import org.apache.jute.InputArchive;
import org.apache.jute.OutputArchive;
import org.apache.jute.Record;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 oa, String tag) throws java.io.IOException {oa.startRecord(this, tag);oa.writeLong(sessionId, "sessionId");oa.writeString(type, "type");oa.endRecord(this, tag);}public void deserialize(InputArchive ia, String tag) throws java.io.IOException {ia.startRecord(tag);this.sessionId = ia.readLong("sessionId");this.type = ia.readString("type");ia.endRecord(tag);}@Overridepublic String toString() {return "sessionId = " + sessionId + ", type = " + type;}
}

Main 

package com.hust.grid.leesf.jute.examples;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;import org.apache.jute.BinaryInputArchive;
import org.apache.jute.BinaryOutputArchive;
import org.apache.zookeeper.server.ByteBufferInputStream;public class Main {public static void main(String[] args) throws IOException {ByteArrayOutputStream baos = new ByteArrayOutputStream();BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);new MockReHeader(0x3421eccb92a34el, "ping").serialize(boa, "header");ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());ByteBufferInputStream bbis = new ByteBufferInputStream(bb);BinaryInputArchive bia = BinaryInputArchive.getArchive(bbis);MockReHeader header2 = new MockReHeader();System.out.println(header2);header2.deserialize(bia, "header");System.out.println(header2);bbis.close();baos.close();    }
}

运行结果

sessionId = 0, type = null
sessionId = 14673999700337486, type = ping

  说明:可以看到MockReHeader实体类需要实现Record接口并且实现serialize和deserialize方法。

  OutputArchive和InputArchive分别是Jute底层的序列化器和反序列化器。

  在Zookeeper的src文件夹下有zookeeper.jute文件,其内容如下  

/*** Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements.  See the NOTICE file* distributed with this work for additional information* regarding copyright ownership.  The ASF licenses this file* to you under the Apache License, Version 2.0 (the* "License"); you may not use this file except in compliance* with the License.  You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/module org.apache.zookeeper.data {class Id {ustring scheme;ustring id;}class ACL {int perms;Id id;}// information shared with the clientclass Stat {long czxid;      // created zxidlong mzxid;      // last modified zxidlong ctime;      // createdlong mtime;      // last modifiedint version;     // versionint cversion;    // child versionint aversion;    // acl versionlong ephemeralOwner; // owner id if ephemeral, 0 otwint dataLength;  //length of the data in the nodeint numChildren; //number of children of this nodelong pzxid;      // last modified children}// information explicitly stored by the server persistentlyclass StatPersisted {long czxid;      // created zxidlong mzxid;      // last modified zxidlong ctime;      // createdlong mtime;      // last modifiedint version;     // versionint cversion;    // child versionint aversion;    // acl versionlong ephemeralOwner; // owner id if ephemeral, 0 otwlong pzxid;      // last modified children}// information explicitly stored by the version 1 database of servers class StatPersistedV1 {long czxid; //created zxidlong mzxid; //last modified zxidlong ctime; //createdlong mtime; //last modifiedint version; //versionint cversion; //child versionint aversion; //acl versionlong ephemeralOwner; //owner id if ephemeral. 0 otw}
}module org.apache.zookeeper.proto {class ConnectRequest {int protocolVersion;long lastZxidSeen;int timeOut;long sessionId;buffer passwd;}class ConnectResponse {int protocolVersion;int timeOut;long sessionId;buffer passwd;}class SetWatches {long relativeZxid;vector<ustring>dataWatches;vector<ustring>existWatches;vector<ustring>childWatches;}        class RequestHeader {int xid;int type;}class MultiHeader {int type;boolean done;int err;}class AuthPacket {int type;ustring scheme;buffer auth;}class ReplyHeader {int xid;long zxid;int err;}class GetDataRequest {ustring path;boolean watch;}class SetDataRequest {ustring path;buffer data;int version;}class SetDataResponse {org.apache.zookeeper.data.Stat stat;}class GetSASLRequest {buffer token;}class SetSASLRequest {buffer token;}class SetSASLResponse {buffer token;}class CreateRequest {ustring path;buffer data;vector<org.apache.zookeeper.data.ACL> acl;int flags;}class DeleteRequest {ustring path;int version;}class GetChildrenRequest {ustring path;boolean watch;}class GetChildren2Request {ustring path;boolean watch;}class CheckVersionRequest {ustring path;int version;}class GetMaxChildrenRequest {ustring path;}class GetMaxChildrenResponse {int max;}class SetMaxChildrenRequest {ustring path;int max;}class SyncRequest {ustring path;}class SyncResponse {ustring path;}class GetACLRequest {ustring path;}class SetACLRequest {ustring path;vector<org.apache.zookeeper.data.ACL> acl;int version;}class SetACLResponse {org.apache.zookeeper.data.Stat stat;}class WatcherEvent {int type;  // event typeint state; // state of the Keeper client runtimeustring path;}class ErrorResponse {int err;}class CreateResponse {ustring path;}class ExistsRequest {ustring path;boolean watch;}class ExistsResponse {org.apache.zookeeper.data.Stat stat;}class GetDataResponse {buffer data;org.apache.zookeeper.data.Stat stat;}class GetChildrenResponse {vector<ustring> children;}class GetChildren2Response {vector<ustring> children;org.apache.zookeeper.data.Stat stat;}class GetACLResponse {vector<org.apache.zookeeper.data.ACL> acl;org.apache.zookeeper.data.Stat stat;}
}module org.apache.zookeeper.server.quorum {class LearnerInfo {long serverid;int protocolVersion;}class QuorumPacket {int type; // Request, Ack, Commit, Pinglong zxid;buffer data; // Only significant when type is requestvector<org.apache.zookeeper.data.Id> authinfo;}
}module org.apache.zookeeper.server.persistence {class FileHeader {int magic;int version;long dbid;}
}module org.apache.zookeeper.txn {class TxnHeader {long clientId;int cxid;long zxid;long time;int type;}class CreateTxnV0 {ustring path;buffer data;vector<org.apache.zookeeper.data.ACL> acl;boolean ephemeral;}class CreateTxn {ustring path;buffer data;vector<org.apache.zookeeper.data.ACL> acl;boolean ephemeral;int parentCVersion;}class DeleteTxn {ustring path;}class SetDataTxn {ustring path;buffer data;int version;}class CheckVersionTxn {ustring path;int version;}class SetACLTxn {ustring path;vector<org.apache.zookeeper.data.ACL> acl;int version;}class SetMaxChildrenTxn {ustring path;int max;}class CreateSessionTxn {int timeOut;}class ErrorTxn {int err;}class Txn {int type;buffer data;}class MultiTxn {vector<org.apache.zookeeper.txn.Txn> txns;}
}

  其定义了所有的实体类的所属包名、类名及类的所有成员变量和类型,该文件会在源代码编译时,Jute会使用不同的代码生成器为这些类定义生成实际编程语言的类文件,如java语言生成的类文件保存在src/java/generated目录下,每个类都会实现Record接口。

二、通信协议

  基于TCP/IP协议,Zookeeper实现了自己的通信协议来玩按成客户端与服务端、服务端与服务端之间的网络通信,对于请求,主要包含请求头和请求体,对于响应,主要包含响应头和响应体。

  3.1 请求协议

  对于请求协议而言,如下为获取节点数据请求的完整协议定义

    class RequestHeader {int xid;int type;}

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

  协议的请求主体内容部分,包含了请求的所有操作内容,不同的请求类型请求体不同。对于会话创建而言,其请求体如下

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

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

  对于获取节点数据而言,其请求体如下  

    class GetDataRequest {ustring path;boolean watch;}

  Zookeeper客户端在向服务器发送节点数据请求时,会发送GetDataRequest请求,该请求包含了数据节点路径path、是否注册Watcher的标识watch。

  对于更新节点数据而言,其请求体如下  

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

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

  针对不同的请求类型,Zookeeper都会定义不同的请求体,可以在zookeeper.jute中查看。

  3.2 响应协议

  对于响应协议而言,如下为获取节点数据响应的完整协议定义

响应头中包含了每个响应最基本的信息,包括xid、zxid和err:

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

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

  协议的响应主体内容部分,包含了响应的所有数据,不同的响应类型请求体不同。对于会话创建而言,其响应体如下  

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

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

  对于获取节点数据而言,其响应体如下 

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

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

  对于更新节点数据而言,其响应体如下 

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

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

  针对不同的响应类型,Zookeeper都会定义不同的响应体,可以在zookeeper.jute中查看。

Zookeeper序列化及通信协议相关推荐

  1. Zookeeper——序列化与反序列化原理

    摘要 我们大概清楚了使用 ZooKeeper 实现一些功能的主要方式,也就是通过客户端与服务端之间的相互通信.那么首先要解决的问题就是通过网络传输数据,而要想通过网络传输我们定义好的 Java 对象数 ...

  2. Zookeeper 序列化

    读完这篇文章你将会收获到 在 Zookeeper 源码项目中新建模块,使用 Jute 进行序列化和反序列化 修改 Jute 中的 buffer size 来序列化/反序列化大对象 序言 从 前面的文章 ...

  3. Zookeeper序列化组件Jute分析

    2019独角兽企业重金招聘Python工程师标准>>> 简介 Jute是Zookeeper中的序列化组件,最初也是Hadoop中的默认序列化组件,前身就是Hadoop Record ...

  4. java基础巩固-宇宙第一AiYWM:为了维持生计,手写RPC~Version07(RPC原理、序列化框架们、网络协议框架们 、RPC 能帮助我们做什么呢、RPC异常排查:ctrl+F搜超时)整起

    上次Version06说到了咱们手写迷你版RPC的大体流程, 对咱们的迷你版RPC的大体流程再做几点补充: 为什么要封装网络协议,别人说封装好咱们就要封装?Java有这个特性那咱就要用?好像是这样.看 ...

  5. java.beans.transient_@Transient注解的使用(不被序列化和作为临时变量存储)

    java 的transient关键字的作用是需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中. trans ...

  6. zookeeper收尾+dubbo前瞻

    2019独角兽企业重金招聘Python工程师标准>>> zookeeper是一个开源的分布式协调框架:数据发布订阅,负载均衡,集群,master选举. 原子性:要么同时成功,要么同是 ...

  7. zookeeper 原理及使用场景2

    数据发布订阅/ 配置中心 实现配置信息的集中式管理和数据的动态更新 实现配置中心有两种模式:push .pull. 长轮训 zookeeper采用的是推拉相结合的方式. 客户端向服务器端注册自己需要关 ...

  8. SpringCloud基础

    文章目录 1. 微服务的基础知识 1.1 单体应用架构 1.2 垂直应用架构 1.3 分布式SOA架构 1.4 微服务架构 1.5 SOA与微服务的关系 1.6 分布式核心知识 1.6.1 分布式中的 ...

  9. Spring Cloud Alibaba微服务组件快速上手

    文章目录 Nacos 什么是Nacos Nacos的启动 将项目注册到Nacos 项目pom依赖 yaml配置 Nacos心跳机制 Dubbo 什么是RPC 什么是Dubbo Dubbo服务的注册与发 ...

最新文章

  1. mysql json_set多维_mysql之json高级使用
  2. 在哪里能收到python实例代码-python仿evething的文件搜索器实例代码
  3. thunderbird怎样方便的导入gmail联系人
  4. 不得不推荐的一本好书《观止》
  5. 【Linux基础 11】vi和vim编辑器的使用
  6. java 视图解析器_SpringMVC——视图和视图解析器
  7. day12 python学习随笔 中
  8. windows上dmg转换cdr_cdr中常见问题及其解决方案
  9. python手机版教程视频_Python教学app下载
  10. 面试IT公司的时候,程序员的简历应该写多少个项目经验比较合适?
  11. 战地1服务器怎么显示fps,《战地1》显示FPS帧数方法介绍 怎么显示FPS帧数
  12. 手游客户端开发招聘要求
  13. web利用html2canvas实现截图上传图片
  14. 流利说 Level 5 全文
  15. 常用快递电子面单接口API对接方法
  16. 【STM32】定时器TIM触发ADC采样,DMA搬运到内存(超详细讲解)
  17. python编程入门课 视频-为了学习Python,我汇总了这10个免费的视频课程!
  18. java的Stream流
  19. 关闭笔记本电脑触控板的方法
  20. 51单片机LED流水灯

热门文章

  1. VB中If与ElseIf的区别
  2. 载波聚合mac_Lte-a终端测试仪表在载波聚合下mac层数据调度方法
  3. 硬件学习应涉及到的几个方面?
  4. vue项目添加ico(已修改)
  5. 【java】CGLIB动态代理原理
  6. Dynamics Ax 微软官方社区地址
  7. 比较五种搜索Rapidshare的方法
  8. svpwm的matlab仿真实现
  9. 笔记本上建立WIFI供安卓手机使用
  10. jfs jfs2_故障诊断过程因JFS2 inode带有空扩展属性条目而挂起