Zookeeper 源码(二)序列化组件 Jute
Zookeeper 源码(二)序列化组件 Jute
一、序列化组件 Jute
对于一个网络通信,首先需要解决的就是对数据的序列化和反序列化处理,在 ZooKeeper 中,使用了Jute 这一序列化组件来进行数据的序列化和反序列化操作。同时,为了实现一个高效的网络通信程序,良好的通信协议设计也是至关重要的。Zookeeper 团队曾想过将 Jute 替换成 Apache 的 Avro 或是 Google 的 protobuf 但是考虑到新老版本序列化组件的兼容性和当前 Jute 的序列化能力并不是 ZooKeeper 的性能瓶颈。
import org.apache.jute.*;
import org.apache.zookeeper.server.ByteBufferInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class JuteHeader implements Record {
private long sessionId;
private String type;
public JuteHeader() {
}
public JuteHeader(long sessionId, String type) {
this.sessionId = sessionId;
this.type = type;
}
@Override
public void serialize(OutputArchive outputArchive, String tag) throws IOException {
outputArchive.startRecord(this, tag);
outputArchive.writeLong(sessionId, "sessionId");
outputArchive.writeString(type, "type");
outputArchive.endRecord(this, tag);
}
@Override
public void deserialize(InputArchive inputArchive, String tag) throws IOException {
inputArchive.startRecord(tag);
sessionId = inputArchive.readLong("sessionId");
type = inputArchive.readString("type");
inputArchive.endRecord(tag);
}
public static void main(String[] args) throws IOException {
final String tag = "header";
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
new JuteHeader(100001L, "xxx").serialize(boa, tag);
// 包装成 ByteBuffer 用于网络传输
ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
// 反序列化
ByteBufferInputStream bbis = new ByteBufferInputStream(bb);
BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis);
JuteHeader header = new JuteHeader();
header.deserialize(bbia, tag);
baos.close();
bbis.close();
}
}
二、Zookeeper 通信协议
基于 TCP/IP 协议,ZooKeeper 实现了自己的通信协议来完成客户端与服务端、服务端与服务端之间的网络通信。ZooKeeper 通信协议整体上的设计非常简单,对于请求,主要包含请求头和请求体,而对于晌应,则主要包含响应头和响应体,
协议的请求头组成如下:
Packet 类中的 createBB() 将 packet 对象序列化:
public void createBB() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
boa.writeInt(-1, "len"); // We'll fill this in later
if (requestHeader != null) {
requestHeader.serialize(boa, "header");
}
if (request instanceof ConnectRequest) {
request.serialize(boa, "connect");
// append "am-I-allowed-to-be-readonly" flag
boa.writeBool(readOnly, "readOnly");
} else if (request != null) {
request.serialize(boa, "request");
}
baos.close();
this.bb = ByteBuffer.wrap(baos.toByteArray());
this.bb.putInt(this.bb.capacity() - 4);
this.bb.rewind();
} catch (IOException e) {
LOG.warn("Ignoring unexpected exception", e);
}
}
请求头:
public class RequestHeader implements Record {
private int xid;
private int type;
public void serialize(OutputArchive a_, String tag) throws java.io.IOException {
a_.startRecord(this,tag);
a_.writeInt(xid,"xid");
a_.writeInt(type,"type");
a_.endRecord(this,tag);
}
public void deserialize(InputArchive a_, String tag) throws java.io.IOException {
a_.startRecord(tag);
xid=a_.readInt("xid");
type=a_.readInt("type");
a_.endRecord(tag);
}
}
请求体有多种,如 ConnectRequest、CreateRequest ...:
public class ConnectRequest implements Record {
private int protocolVersion;
private long lastZxidSeen;
private int timeOut;
private long sessionId;
private byte[] passwd;
public void serialize(OutputArchive a_, String tag) throws java.io.IOException {
a_.startRecord(this,tag);
a_.writeInt(protocolVersion,"protocolVersion");
a_.writeLong(lastZxidSeen,"lastZxidSeen");
a_.writeInt(timeOut,"timeOut");
a_.writeLong(sessionId,"sessionId");
a_.writeBuffer(passwd,"passwd");
a_.endRecord(this,tag);
}
public void deserialize(InputArchive a_, String tag) throws java.io.IOException {
a_.startRecord(tag);
protocolVersion=a_.readInt("protocolVersion");
lastZxidSeen=a_.readLong("lastZxidSeen");
timeOut=a_.readInt("timeOut");
sessionId=a_.readLong("sessionId");
passwd=a_.readBuffer("passwd");
a_.endRecord(tag);
}
}
每天用心记录一点点。内容也许不重要,但习惯很重要!
Zookeeper 源码(二)序列化组件 Jute的更多相关文章
- zookeeper源码 — 二、集群启动—leader选举
上一篇介绍了zookeeper的单机启动,集群模式下启动和单机启动有相似的地方,但是也有各自的特点.集群模式的配置方式和单机模式也是不一样的,这一篇主要包含以下内容: 概念介绍:角色,服务器状态 服务 ...
- ZooKeeper源码阅读——client(二)
原创技术文章,转载请注明:转自http://newliferen.github.io/ 如何连接ZooKeeper集群 要想了解ZooKeeper客户端实现原理,首先需要关注一下客户端的使用方式, ...
- Zookeeper源码(启动+选举)
简介 关于Zookeeper,目前普遍的应用场景基本作为服务注册中心,用于服务发现.但这只是Zookeeper的一个的功能,根据Apache的官方概述:"The Apache ZooKeep ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- Zookeeper 源码(三)Zookeeper 客户端源码
Zookeeper 源码(三)Zookeeper 客户端源码 Zookeeper 客户端主要有以下几个重要的组件.客户端会话创建可以分为三个阶段:一是初始化阶段.二是会话创建阶段.三是响应处理阶段. ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- Unity UGUI图文混排源码(二)
Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...
- Django-restframework 源码之认证组件源码分析
Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...
- Tomcat8源码笔记(七)组件启动Server Service Engine Host启动
一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...
随机推荐
- UVAlive5713 Qin Shi Huang's National Road System【次小生成树】【DP】
LINK1 LINK2 题目大意 给你平面上的n个点 每个点有一个权值 让你求出一个生成树 可以选择一条边不花费代价 要最大化这条边两边端点的权值/剩下n-2条边的长度之和 思路 发现发现其实端点权值 ...
- java第十次面试题
一.给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg,字符串内的其他字符不改变,给定函数,编写函数. public static void ...
- Anatoly and Cockroaches
Anatoly lives in the university dorm as many other students do. As you know, cockroaches are also li ...
- 老爷机iphone4s 9.2.1降级6.1.3
原帖见威锋网 sunnyskyline 2017年1月10日发的贴. 本文中加了一些我自己的情况,也是一知半解,抛砖引玉吧. 首先进行备份.进行备份.进行备份. 感谢大神@极端阴险 感谢@shuaig ...
- @vue/cli 3配置文件vue.config.js
const webpack = require('webpack') const path = require('path') // const CompressionWebpackPlugin = ...
- Linux内核编译技巧
1.将多个文件编译成一个模块,部分文件可选 Example1: drivers/usb/core/Makefile:usbcore-y := usb.o hub.o hcd.o urb.o messa ...
- fusionjs 学习一 基本试用
参考demo 项目 https://github.com/rongfengliang/fusionjs-docker-demo 安装 create startkit yarn global add c ...
- centos7 安装配置rsyslog + LogAnalyzer + mysql
https://www.cnblogs.com/mchina/p/linux-centos-rsyslog-loganalyzer-mysql-log-server.html 安装LNMP 一键安装包 ...
- 插入排序算法-python实现
#-*- coding: UTF-8 -*- import numpy as np def InsertSort(a): for i in xrange(1,a.size): for j in xra ...
- week2--线性表
一.PTA实验作业 题目1:顺序表删除重复元素(6-3) 设计思路 代码截图 PTA提交列表说明 编译错误:写'->'符号的时候总是漏掉'>'; 写'!='符号的时候漏写'!'; 解决方法 ...