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://javaforall.net/199504.html原文链接:https://javaforall.net
