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