摘要:在版本中,支持五種序列化方式,分別是依賴阿里的庫,功能強大支持普通類包括任意或完全兼容序列化協(xié)議的系列化框架,序列化速度大概是的倍,大小是大小的左右。但這里實際不是原生的序列化,而是阿里修改過的,它是默認啟用的序列化方式自帶的序列化實現(xiàn)。
序列化——開篇
目標:介紹dubbo中序列化的內(nèi)容,對dubbo中支持的序列化方式做對比,介紹dubbo-serialization-api下的源碼前言
序列化就是將對象轉(zhuǎn)成字節(jié)流,用于網(wǎng)絡傳輸,以及將字節(jié)流轉(zhuǎn)為對象,用于在收到字節(jié)流數(shù)據(jù)后還原成對象。序列化的好處我就不多說了,無非就是安全性更好、可跨平臺等。網(wǎng)上有很多總結的很好,我在這里主要講講dubbo中序列化的設計和實現(xiàn)了哪些序列化方式。
dubbo在2.6.x版本中,支持五種序列化方式,分別是
fastjson:依賴阿里的fastjson庫,功能強大(支持普通JDK類包括任意Java Bean Class、Collection、Map、Date或enum)
fst:完全兼容JDK序列化協(xié)議的系列化框架,序列化速度大概是JDK的4-10倍,大小是JDK大小的1/3左右。
hessian2:hessian是一種跨語言的高效二進制序列化方式。但這里實際不是原生的hessian2序列化,而是阿里修改過的hessian lite,它是dubbo RPC默認啟用的序列化方式
jdk:JDK自帶的Java序列化實現(xiàn)。
kryo:是一個快速序列化/反序列化工具,其使用了字節(jié)碼生成機制(底層依賴了 ASM 庫),因此具有比較好的運行速度,速度快,序列化后體積小,跨語言支持較復雜
在dubbo最新的2.7.0版本中支持了protostuff,之前的版本dubbo還實現(xiàn)了自己的dubbo序列化,但是由于還不夠成熟,所有暫時移除了dubbo序列化的實現(xiàn)。
從性能上對比,fst和kryo>hessian2>fastjson>jdk。
他們具體的實現(xiàn)我不講解,因為很多都直接使用了對應的依賴褲,我只講解dubbo序列化的接口設計。
源碼分析 (一)DataInputpublic interface DataInput { /** * Read boolean. * 讀取布爾類型 * @return boolean. * @throws IOException */ boolean readBool() throws IOException; /** * Read byte. * 讀取字節(jié) * @return byte value. * @throws IOException */ byte readByte() throws IOException; /** * Read short integer. * 讀取short類型 * @return short. * @throws IOException */ short readShort() throws IOException; /** * Read integer. * 讀取integer類型 * @return integer. * @throws IOException */ int readInt() throws IOException; /** * Read long. * 讀取long類型 * @return long. * @throws IOException */ long readLong() throws IOException; /** * Read float. * 讀取float類型 * @return float. * @throws IOException */ float readFloat() throws IOException; /** * Read double. * 讀取double類型 * @return double. * @throws IOException */ double readDouble() throws IOException; /** * Read UTF-8 string. * 讀取UTF-8 string * @return string. * @throws IOException */ String readUTF() throws IOException; /** * Read byte array. * 讀取byte數(shù)組 * @return byte array. * @throws IOException */ byte[] readBytes() throws IOException; }
該接口是數(shù)據(jù)輸入接口,可以看到定義了從 InputStream 中各類數(shù)據(jù)類型的讀取方法。
(二)DataOutputpublic interface DataOutput { /** * Write boolean. * 輸出boolean類型 * @param v value. * @throws IOException */ void writeBool(boolean v) throws IOException; /** * Write byte. * 輸出byte類型 * @param v value. * @throws IOException */ void writeByte(byte v) throws IOException; /** * Write short. * 輸出short類型 * @param v value. * @throws IOException */ void writeShort(short v) throws IOException; /** * Write integer. * 輸出integer類型 * @param v value. * @throws IOException */ void writeInt(int v) throws IOException; /** * Write long. * 輸出long類型 * @param v value. * @throws IOException */ void writeLong(long v) throws IOException; /** * Write float. * 輸出float類型 * @param v value. * @throws IOException */ void writeFloat(float v) throws IOException; /** * Write double. * 輸出double類型 * @param v value. * @throws IOException */ void writeDouble(double v) throws IOException; /** * Write string. * 輸出string類型 * @param v value. * @throws IOException */ void writeUTF(String v) throws IOException; /** * Write byte array. * 輸出byte數(shù)組 * @param v value. * @throws IOException */ void writeBytes(byte[] v) throws IOException; /** * Write byte array. * 輸出byte數(shù)組中部分數(shù)據(jù) * @param v value. * @param off offset. * @param len length. * @throws IOException */ void writeBytes(byte[] v, int off, int len) throws IOException; /** * Flush buffer. * 刷新緩沖區(qū) * @throws IOException */ void flushBuffer() throws IOException; }
該接口是數(shù)據(jù)輸出接口,可以看到定義了向 InputStream 中,寫入基本類型的數(shù)據(jù)。
(三)ObjectOutputpublic interface ObjectOutput extends DataOutput { /** * write object. * 輸入object類型 * @param obj object. */ void writeObject(Object obj) throws IOException; }
在 DataOutput 的基礎上,增加寫入object類型的數(shù)據(jù)。
(四)ObjectInputpublic interface ObjectInput extends DataInput { /** * read object. * 讀取object類型數(shù)據(jù) * @return object. */ Object readObject() throws IOException, ClassNotFoundException; /** * read object. * 根據(jù)class類型讀取object類型數(shù)據(jù) * @param cls object type. * @return object. */T readObject(Class cls) throws IOException, ClassNotFoundException; /** * read object. * 取object類型數(shù)據(jù) * @param cls object type. * @return object. */ T readObject(Class cls, Type type) throws IOException, ClassNotFoundException; }
該接口是繼承了DataInput 接口,在 DataInput 的基礎上,增加讀取object類型的數(shù)據(jù)。
(五)Cleanablepublic interface Cleanable { /** * 清理 */ void cleanup(); }
該接口是清理接口,定義了一個清理方法。目前只有kryo實現(xiàn)的時候,完成序列化或反序列化,需要做清理。通過實現(xiàn)該接口,執(zhí)行清理的邏輯。
(六)Serialization@SPI("hessian2") public interface Serialization { /** * get content type id * 獲得內(nèi)容類型編號 * @return content type id */ byte getContentTypeId(); /** * get content type * 獲得內(nèi)容類型名 * @return content type */ String getContentType(); /** * create serializer * 創(chuàng)建 ObjectOutput 對象,序列化輸出到 OutputStream * @param url * @param output * @return serializer * @throws IOException */ @Adaptive ObjectOutput serialize(URL url, OutputStream output) throws IOException; /** * create deserializer * 創(chuàng)建 ObjectInput 對象,從 InputStream 反序列化 * @param url * @param input * @return deserializer * @throws IOException */ @Adaptive ObjectInput deserialize(URL url, InputStream input) throws IOException; }
該接口是序列化接口,該接口也是可擴展接口,默認是使用hessian2序列化方式。其中定義了序列化和反序列化等方法
(七)SerializableClassRegistrypublic abstract class SerializableClassRegistry { /** * 可序列化類類的集合 */ private static final Setregistrations = new LinkedHashSet (); /** * only supposed to be called at startup time * 把可序列化的類加入到集合 */ public static void registerClass(Class clazz) { registrations.add(clazz); } /** * 獲得可序列化的類的集合 * @return */ public static Set getRegisteredClasses() { return registrations; } }
該類提供一個序列化統(tǒng)一的注冊中心,其實就是封裝了可序列化類的集合
(八)SerializationOptimizerpublic interface SerializationOptimizer { /** * 需要序列化的類的集合 * @return */ CollectiongetSerializableClasses(); }
該接口序列化優(yōu)化器接口,在 Kryo 、FST 中,支持配置需要優(yōu)化的類。業(yè)務系統(tǒng)中,可以實現(xiàn)自定義的 SerializationOptimizer,進行配置?;蛘呤褂梦募砼渲靡彩且粋€選擇。
后記該部分相關的源碼解析地址:https://github.com/CrazyHZM/i...
該文章講解了dubbo支持的幾種序列化方式,介紹了序列化的接口設計,具體的實現(xiàn)我不再講述,因為大部分都是調(diào)用了不同的依賴庫。接下來我會說一個分割線,我講開始講解2.7.x版本的新特性,然后分析新特性的實現(xiàn),下一篇就先講解一下dubbo2.7.0的大改動。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/73692.html
摘要:可以參考源碼解析二十四遠程調(diào)用協(xié)議的八。十六的該類也是用了適配器模式,該類主要的作用就是增加了心跳功能,可以參考源碼解析十遠程通信層的四。二十的可以參考源碼解析十七遠程通信的一。 2.7大揭秘——消費端發(fā)送請求過程 目標:從源碼的角度分析一個服務方法調(diào)用經(jīng)歷怎么樣的磨難以后到達服務端。 前言 前一篇文章講到的是引用服務的過程,引用服務無非就是創(chuàng)建出一個代理。供消費者調(diào)用服務的相關方法。...
摘要:大揭秘異步化改造目標從源碼的角度分析的新特性中對于異步化的改造原理。看源碼解析四十六消費端發(fā)送請求過程講到的十四的,在以前的邏輯會直接在方法中根據(jù)配置區(qū)分同步異步單向調(diào)用。改為關于可以參考源碼解析十遠程通信層的六。 2.7大揭秘——異步化改造 目標:從源碼的角度分析2.7的新特性中對于異步化的改造原理。 前言 dubbo中提供了很多類型的協(xié)議,關于協(xié)議的系列可以查看下面的文章: du...
摘要:而存在的意義就是保證請求或響應對象可在線程池中被解碼,解碼完成后,就會分發(fā)到的。 2.7大揭秘——服務端處理請求過程 目標:從源碼的角度分析服務端接收到請求后的一系列操作,最終把客戶端需要的值返回。 前言 上一篇講到了消費端發(fā)送請求的過程,該篇就要將服務端處理請求的過程。也就是當服務端收到請求數(shù)據(jù)包后的一系列處理以及如何返回最終結果。我們也知道消費端在發(fā)送請求的時候已經(jīng)做了編碼,所以我...
摘要:大揭秘目標了解的新特性,以及版本升級的引導。四元數(shù)據(jù)改造我們知道以前的版本只有注冊中心,注冊中心的有數(shù)十個的鍵值對,包含了一個服務所有的元數(shù)據(jù)。 DUBBO——2.7大揭秘 目標:了解2.7的新特性,以及版本升級的引導。 前言 我們知道Dubbo在2011年開源,停止更新了一段時間。在2017 年 9 月 7 日,Dubbo 悄悄的在 GitHub 發(fā)布了 2.5.4 版本。隨后,版本...
摘要:遠程調(diào)用開篇目標介紹之后解讀遠程調(diào)用模塊的內(nèi)容如何編排介紹中的包結構設計以及最外層的的源碼解析。十該類就是遠程調(diào)用的上下文,貫穿著整個調(diào)用,例如調(diào)用,然后調(diào)用。十五該類是系統(tǒng)上下文,僅供內(nèi)部使用。 遠程調(diào)用——開篇 目標:介紹之后解讀遠程調(diào)用模塊的內(nèi)容如何編排、介紹dubbo-rpc-api中的包結構設計以及最外層的的源碼解析。 前言 最近我面臨著一個選擇,因為dubbo 2.7.0-...
閱讀 3255·2021-11-11 16:55
閱讀 2567·2021-10-13 09:39
閱讀 2467·2021-09-13 10:27
閱讀 2181·2019-08-30 15:55
閱讀 3106·2019-08-30 15:54
閱讀 3154·2019-08-29 16:34
閱讀 1848·2019-08-29 12:41
閱讀 1087·2019-08-29 11:33