Zookeeper的客户端和服务端会进行一系列的网络通信以实现数据传输,对于一个网络通信,首先要解决的就是对数据的序列化和反序列化;
ZK使用jute这一序列化组件来进行数据的序列化和反序列化;
使用Jute进行序列化:看一段代码:
1 import org.apache.jute.Record; 2 3 public class MockReqHeader implements Record { 4 private long sessionId; 5 private String type; 6 public MockReqHeader() {} 7 public MockReqHeader( long sessionId, String type ) { 8 this.sessionId = sessionId; 9 this.type = type; 10 } 11 public long getSessionId() { 12 return sessionId; 13 } 14 public void setSessionId( long sessionId ) { 15 this.sessionId = sessionId; 16 } 17 public String getType() { 18 return type; 19 } 20 public void setType( String m_ ){ 21 type = m_; 22 } 23 public void serialize( OutputArchive a, String tag ) throws java.io.IOException { 24 a.startRecord( this, tag ); 25 a.writeLong( sessionId, "sessionId" ); 26 a.writeString( type, "type" ); 27 a.endRecord( this, tag ); 28 } 29 public void deserialize( InputArchive b, String tag ) throws java.io.IOException { 30 b.startRecord( tag ); 31 sessionId = b.readLong( "sessionId" ); 32 type = b.readString( "type" ); 33 b.endRecord( tag ); 34 } 35 } 36 37 /*注意serialize和deserialize方法*/
MockReqHeader实体类的序列化和反序列化;
1 import org.apache.jute.BinaryInputArchive; 2 import org.apache.jute.BinaryOutputArchive; 3 4 public class JuteSample{ 5 public static void main( String[] args ) throws Exception { 6 //开始序列化,并且构造一个序列化器BinaryOutputArchive 7 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 8 BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos); 9 //将对象序列化到header中去; 10 new MockReqHeader( 0x34221eccb92a34el, "ping" ).serialize(boa, "header"); 11 //这里通常是TCP网络传输对象 12 ByteBuffer bb = ByteBuffer.wrap( baos.toByteArray() ); 13 14 //开始反序列化 15 ByteBufferInputStream bbis = new ByteBufferInputStream(bb); 16 BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis); 17 MockReqHeader header2 = new MockReqHeader(); 18 //从header中反序列化; 19 header2.deserialize(bbia, "header"); 20 bbis.close(); 21 baos.close(); 22 } 23 }
上面的实例中,我们提到了Record序列化接口,序列化器BinaryOutOoutArchive,现在从这两方面以及jute的配置文件去了解jute;
1 . Record接口
该接口只有两个方法:public void serialize( OutputArchive a_, String tag );public void deserialize( InputArchive a_, String tag );
所有的实体类通过实现Record接口的这两个方法,来确定自己将如何被序列化和反序列化,其中Archive是正在的序列化和反序列化器,tag为序列化和反序列化的标识;
2 . OutputArchive和InputArchive
这两个接口分别是jute底层的序列化器和反序列化器;
最新的jute版本中:BinaryOutputArchive/BinaryInputArchive; Csv* ; Xml*;三组;
BinaryOutputArchive对数据对象序列化和反序列化,主要用于进行网络传输和本地磁盘传输,是ZK底层最主要的序列化方式;
3 . jute的配置文件
在Zzookeeper的src目录下,有一个名叫zookeeper.jute的文件;
//zookeeper定义 module org.apache.zookeeper.data{ class Id{ ustring scheme; ustring id; } class ACL{ int prems; Id id; } …… }
在这个文件中,定义了所有实体类的所属包名,类名,以及该类的所有成员变量及其类型;例如上述,定义了Id和ACL两个类;
这个定义文件在源码编译阶段,jute会使用不同的代码生成器为这些类定义生成实际的编程语言的类文件;
Zookeeper内部实现分布式数据一致性(序列化和协议)(四)
原文:https://www.cnblogs.com/startelk/p/11764044.html