摘要:在版本中,支持五種序列化方式,分別是依賴阿里的庫,功能強(qiáng)大支持普通類包括任意或完全兼容序列化協(xié)議的系列化框架,序列化速度大概是的倍,大小是大小的左右。但這里實(shí)際不是原生的序列化,而是阿里修改過的,它是默認(rèn)啟用的序列化方式自帶的序列化實(shí)現(xiàn)。
序列化——開篇
目標(biāo):介紹dubbo中序列化的內(nèi)容,對(duì)dubbo中支持的序列化方式做對(duì)比,介紹dubbo-serialization-api下的源碼前言
序列化就是將對(duì)象轉(zhuǎn)成字節(jié)流,用于網(wǎng)絡(luò)傳輸,以及將字節(jié)流轉(zhuǎn)為對(duì)象,用于在收到字節(jié)流數(shù)據(jù)后還原成對(duì)象。序列化的好處我就不多說了,無非就是安全性更好、可跨平臺(tái)等。網(wǎng)上有很多總結(jié)的很好,我在這里主要講講dubbo中序列化的設(shè)計(jì)和實(shí)現(xiàn)了哪些序列化方式。
dubbo在2.6.x版本中,支持五種序列化方式,分別是
fastjson:依賴阿里的fastjson庫,功能強(qiáng)大(支持普通JDK類包括任意Java Bean Class、Collection、Map、Date或enum)
fst:完全兼容JDK序列化協(xié)議的系列化框架,序列化速度大概是JDK的4-10倍,大小是JDK大小的1/3左右。
hessian2:hessian是一種跨語言的高效二進(jìn)制序列化方式。但這里實(shí)際不是原生的hessian2序列化,而是阿里修改過的hessian lite,它是dubbo RPC默認(rèn)啟用的序列化方式
jdk:JDK自帶的Java序列化實(shí)現(xiàn)。
kryo:是一個(gè)快速序列化/反序列化工具,其使用了字節(jié)碼生成機(jī)制(底層依賴了 ASM 庫),因此具有比較好的運(yùn)行速度,速度快,序列化后體積小,跨語言支持較復(fù)雜
在dubbo最新的2.7.0版本中支持了protostuff,之前的版本dubbo還實(shí)現(xiàn)了自己的dubbo序列化,但是由于還不夠成熟,所有暫時(shí)移除了dubbo序列化的實(shí)現(xiàn)。
從性能上對(duì)比,fst和kryo>hessian2>fastjson>jdk。
他們具體的實(shí)現(xiàn)我不講解,因?yàn)楹芏喽贾苯邮褂昧藢?duì)應(yīng)的依賴褲,我只講解dubbo序列化的接口設(shè)計(jì)。
源碼分析 (一)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ù)組中部分?jǐn)?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 的基礎(chǔ)上,增加寫入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 的基礎(chǔ)上,增加讀取object類型的數(shù)據(jù)。
(五)Cleanablepublic interface Cleanable { /** * 清理 */ void cleanup(); }
該接口是清理接口,定義了一個(gè)清理方法。目前只有kryo實(shí)現(xiàn)的時(shí)候,完成序列化或反序列化,需要做清理。通過實(shí)現(xiàn)該接口,執(zhí)行清理的邏輯。
(六)Serialization@SPI("hessian2") public interface Serialization { /** * get content type id * 獲得內(nèi)容類型編號(hào) * @return content type id */ byte getContentTypeId(); /** * get content type * 獲得內(nèi)容類型名 * @return content type */ String getContentType(); /** * create serializer * 創(chuàng)建 ObjectOutput 對(duì)象,序列化輸出到 OutputStream * @param url * @param output * @return serializer * @throws IOException */ @Adaptive ObjectOutput serialize(URL url, OutputStream output) throws IOException; /** * create deserializer * 創(chuàng)建 ObjectInput 對(duì)象,從 InputStream 反序列化 * @param url * @param input * @return deserializer * @throws IOException */ @Adaptive ObjectInput deserialize(URL url, InputStream input) throws IOException; }
該接口是序列化接口,該接口也是可擴(kuò)展接口,默認(rèn)是使用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; } }
該類提供一個(gè)序列化統(tǒng)一的注冊(cè)中心,其實(shí)就是封裝了可序列化類的集合
(八)SerializationOptimizerpublic interface SerializationOptimizer { /** * 需要序列化的類的集合 * @return */ CollectiongetSerializableClasses(); }
該接口序列化優(yōu)化器接口,在 Kryo 、FST 中,支持配置需要優(yōu)化的類。業(yè)務(wù)系統(tǒng)中,可以實(shí)現(xiàn)自定義的 SerializationOptimizer,進(jìn)行配置。或者使用文件來配置也是一個(gè)選擇。
后記該部分相關(guān)的源碼解析地址:https://github.com/CrazyHZM/i...
該文章講解了dubbo支持的幾種序列化方式,介紹了序列化的接口設(shè)計(jì),具體的實(shí)現(xiàn)我不再講述,因?yàn)榇蟛糠侄际钦{(diào)用了不同的依賴庫。接下來我會(huì)說一個(gè)分割線,我講開始講解2.7.x版本的新特性,然后分析新特性的實(shí)現(xiàn),下一篇就先講解一下dubbo2.7.0的大改動(dòng)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/73692.html
摘要:可以參考源碼解析二十四遠(yuǎn)程調(diào)用協(xié)議的八。十六的該類也是用了適配器模式,該類主要的作用就是增加了心跳功能,可以參考源碼解析十遠(yuǎn)程通信層的四。二十的可以參考源碼解析十七遠(yuǎn)程通信的一。 2.7大揭秘——消費(fèi)端發(fā)送請(qǐng)求過程 目標(biāo):從源碼的角度分析一個(gè)服務(wù)方法調(diào)用經(jīng)歷怎么樣的磨難以后到達(dá)服務(wù)端。 前言 前一篇文章講到的是引用服務(wù)的過程,引用服務(wù)無非就是創(chuàng)建出一個(gè)代理。供消費(fèi)者調(diào)用服務(wù)的相關(guān)方法。...
摘要:大揭秘異步化改造目標(biāo)從源碼的角度分析的新特性中對(duì)于異步化的改造原理。看源碼解析四十六消費(fèi)端發(fā)送請(qǐng)求過程講到的十四的,在以前的邏輯會(huì)直接在方法中根據(jù)配置區(qū)分同步異步單向調(diào)用。改為關(guān)于可以參考源碼解析十遠(yuǎn)程通信層的六。 2.7大揭秘——異步化改造 目標(biāo):從源碼的角度分析2.7的新特性中對(duì)于異步化的改造原理。 前言 dubbo中提供了很多類型的協(xié)議,關(guān)于協(xié)議的系列可以查看下面的文章: du...
摘要:而存在的意義就是保證請(qǐng)求或響應(yīng)對(duì)象可在線程池中被解碼,解碼完成后,就會(huì)分發(fā)到的。 2.7大揭秘——服務(wù)端處理請(qǐng)求過程 目標(biāo):從源碼的角度分析服務(wù)端接收到請(qǐng)求后的一系列操作,最終把客戶端需要的值返回。 前言 上一篇講到了消費(fèi)端發(fā)送請(qǐng)求的過程,該篇就要將服務(wù)端處理請(qǐng)求的過程。也就是當(dāng)服務(wù)端收到請(qǐng)求數(shù)據(jù)包后的一系列處理以及如何返回最終結(jié)果。我們也知道消費(fèi)端在發(fā)送請(qǐng)求的時(shí)候已經(jīng)做了編碼,所以我...
摘要:大揭秘目標(biāo)了解的新特性,以及版本升級(jí)的引導(dǎo)。四元數(shù)據(jù)改造我們知道以前的版本只有注冊(cè)中心,注冊(cè)中心的有數(shù)十個(gè)的鍵值對(duì),包含了一個(gè)服務(wù)所有的元數(shù)據(jù)。 DUBBO——2.7大揭秘 目標(biāo):了解2.7的新特性,以及版本升級(jí)的引導(dǎo)。 前言 我們知道Dubbo在2011年開源,停止更新了一段時(shí)間。在2017 年 9 月 7 日,Dubbo 悄悄的在 GitHub 發(fā)布了 2.5.4 版本。隨后,版本...
摘要:遠(yuǎn)程調(diào)用開篇目標(biāo)介紹之后解讀遠(yuǎn)程調(diào)用模塊的內(nèi)容如何編排介紹中的包結(jié)構(gòu)設(shè)計(jì)以及最外層的的源碼解析。十該類就是遠(yuǎn)程調(diào)用的上下文,貫穿著整個(gè)調(diào)用,例如調(diào)用,然后調(diào)用。十五該類是系統(tǒng)上下文,僅供內(nèi)部使用。 遠(yuǎn)程調(diào)用——開篇 目標(biāo):介紹之后解讀遠(yuǎn)程調(diào)用模塊的內(nèi)容如何編排、介紹dubbo-rpc-api中的包結(jié)構(gòu)設(shè)計(jì)以及最外層的的源碼解析。 前言 最近我面臨著一個(gè)選擇,因?yàn)閐ubbo 2.7.0-...
閱讀 3294·2021-11-11 16:55
閱讀 2668·2021-10-13 09:39
閱讀 2507·2021-09-13 10:27
閱讀 2216·2019-08-30 15:55
閱讀 3146·2019-08-30 15:54
閱讀 3187·2019-08-29 16:34
閱讀 1891·2019-08-29 12:41
閱讀 1127·2019-08-29 11:33