Zookeeper在网络传输时使用的是Jute进行序列化和反序列化,官方也提出过要使用类似于Apache Avro、Thrift或是Google的protobuf这样的组件来替换Jute,但考虑到新老版本组件的兼容性,官方对替换序列化组件工作的推进持保守和观望态度。
下面来看看如何使用Jute来完成对象的序列化和反序列化,以MockReqHeader类为例,需要实现Record接口。
package com.teriste.entity;
import org.apache.jute.InputArchive;
import org.apache.jute.OutputArchive;
import org.apache.jute.Record;
import java.io.IOException;
public class MockReqHeader implements Record{
private long sessionId;
private String type;
public MockReqHeader(){
}
public MockReqHeader(long sessionId,String type){
this.sessionId=sessionId;
this.type=type;
}
public long getSessionId() {
return sessionId;
}
public void setSessionId(long sessionId) {
this.sessionId = sessionId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void serialize(OutputArchive a_, String tag) throws IOException{
a_.startRecord(this,tag);
a_.writeLong(sessionId,"sessionId");
a_.writeString(type,"type");
a_.endRecord(this,tag);
}
public void deserialize(InputArchive a_, String tag) throws IOException{
a_.startRecord(tag);
sessionId=a_.readLong("sessionId");
type=a_.readString("type");
a_.endRecord(tag);
}
@Override
public String toString() {
return "MockReqHeader{" +
"sessionId=" + sessionId +
", type='" + type + '\'' +
'}';
}
}
下面来测试序列化和反序列化:
package com.teriste.web;
import com.teriste.entity.MockReqHeader;
import org.apache.jute.BinaryInputArchive;
import org.apache.jute.BinaryOutputArchive;
import org.apache.zookeeper.server.ByteBufferInputStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
@RunWith(SpringJUnit4ClassRunner.class)
public class JuteTest {
/**
* 实体类要使用Jute进行序列化和反序列化步骤
* 1.需要实现Record接口的serialize和deserialize方法
* 2.构建一个序列化器BinaryOutputArchive
* 3.序列化
* 调用实体类的serialize方法,将对象序列化到指定的tag中去,比如这里将对象序列化到header中
* 4.反序列化
* 调用实体类的deserialize方法,从指定的tag中反序列化出数据内容
*/
@Test
public void serialTest() throws IOException{
//对象序列化
ByteArrayOutputStream baos=new ByteArrayOutputStream();
BinaryOutputArchive boa=BinaryOutputArchive.getArchive(baos);
new MockReqHeader(0x22342eccb43a12al,"ping").serialize(boa,"header");
//TCP忘了传输对象
ByteBuffer bb=ByteBuffer.wrap(baos.toByteArray());
//反序列化
ByteBufferInputStream bbis=new ByteBufferInputStream(bb);
BinaryInputArchive bia=BinaryInputArchive.getArchive(bbis);
MockReqHeader header2=new MockReqHeader();
header2.deserialize(bia,"header");
System.out.println(header2);
bbis.close();
baos.close();
}
}
Record接口
Jute定义了自己独特的序列化格式Record,Zookeeper中所需要进行网络传输或是本地磁盘存储的类型定义,都实现了该接口,其结构简单明了,操作灵活多变,是Jute序列化的核心。Record定义了两个基本的方法,分别是serialize和deserialize,分别用于序列化和反序列化。其中archive是底层真正的序列化器和反序列化器,并且每个archive中可以包含对多个对象的序列化和反序列化,因此两个接口中都标记了参数tag,用于序列化器和反序列化器标识对象自己的标记。
OutputArchive和InputArchive
OutputArchive和InputArchive分别是Jute底层的序列化器和反序列化器定义。有BinaryOutputArchive/BinaryInputArchive、CsvOutputArchive/CsvInputArchive和XmlOutputArchive/XmlInputArchive三种实现,无论哪种实现都是基于OutputStream和InoutStream进行操作。
BinaryOutputArchive对数据对象的序列化和反序列化,主要用于进行网络传输和本地磁盘的存储,是Zookeeper底层最主要的序列化方式。CsvOutputArchive对数据的序列化,更多的是方便数据的可视化展示,因此被用在toString方法中。XmlOutputArchive则是为了将数据对象以xml格式保存和还原,但目前在Zookeeper中基本没使用到。
参考书籍《从Paxos到Zookeeper++分布式一致性原理与实践》
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/75733.html