你們好,今天開始給你們分享 — Dubbo 專題之 Dubbo 序列化。在前一個章節中咱們介紹了 Dubbo 路由規則之標籤路由,其實現原理爲:若是消費端傳遞標籤則和配置的動態規則和靜態規則進行匹配,若是消費端未傳遞標籤則使用服務提供端的本地配置的靜態標籤和動態配置標籤進行匹配。同時咱們也例舉了常見的使用場景而且進行了源碼解析來分析其實現原理。有的小夥伴能夠想知道 Dubbo 中遠程調用數據傳輸是經過哪些方式進行數據的序列化呢?那麼這個章節咱們一塊兒來討論在咱們的 Dubbo 中有哪些序列化方式以及性能表現如何。下面就讓咱們快速開始吧!java
首先咱們得明白什麼是序列化和發序列化,舉個簡單的例子:當咱們須要把一個數據對象寫入到文件或者在網絡中傳輸時,就要把數據對象進行轉換爲二進制格式進行數據傳輸這個過程就叫作序列化,反之若是一個遠程數據或本地文件數據須要讀取並解析爲咱們的對象時就叫作反序列化。在 Dubbo RPC 中,同時支持多種序列化方式:git
下圖是當前2.7.x版本中支持的序列化方式:spring
Dubbo RPC 默認採用 Hessian2 序列化。但 Hessian 是一個比較老的序列化實現了,並且它是跨語言的,因此不是單獨針對 Java 進行優化的。而 Dubbo RPC實際上徹底是一種 Java to Java 的遠程調用,其實沒有必要採用跨語言的序列化方式。最近幾年,各類新的高效序列化方式層出不窮,不斷刷新序列化性能的上限,最典型的包括:apache
其中,Kryo 是一種很是成熟的序列化實現,已經在Twitter、Groupon、Yahoo以及多個著名開源項目(如Hive、Storm)中普遍的使用。而FST是一種較新的序列化實現,目前還缺少足夠多的成熟使用案例。編程
下面咱們主要經過 XML 方式進行配置介紹:json
XML 方式api
<dubbo:protocol name="dubbo" serialization="hession2"/>
這裏使用serialization
來進行序列化方式配置。微信
根據前面的介紹咱們大概理解了什麼是序列化和反序列化,而序列化和反序列化在 Dubbo 中是必須的,那麼 Dubbo 中提供了多種序列化方式咱們應該使用哪種序列化方式呢?咱們先看一個來自官網的性能測試圖:網絡
從上圖能夠看出序列化方式:kyro、FST 性能最優。若是被序列化的類中不包含無參的構造函數,則在 Kryo 的序列化中,性能將會大打折扣,由於此時咱們在底層將用 Java 的序列化來透明的取代 Kryo 序列化。因此,儘量爲每個被序列化的類添加無參構造函數是一種最佳實踐。另外,Kryo 和 FST 原本都不須要被序列化都類實現 Serializable
接口,但咱們仍是建議每一個被序列化類都去實現它,由於這樣能夠保持和 Java 序列化以及 Dubbo 序列化的兼容性。app
下面我以獲取圖書列表爲例進行演示。項目結構以下:
咱們主要看服務提供者端的dubbo-provider-xml.xml
的 XML 配置 :
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!--自定序列化方式爲:hession2 --> <dubbo:protocol port="20880" serialization="hession2"/> <dubbo:application name="demo-provider" metadata-type="remote"/> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <bean id="bookFacade" class="com.muke.dubbocourse.serializable.provider.BookFacadeImpl"/> <!--暴露服務爲Dubbo服務--> <dubbo:service interface="com.muke.dubbocourse.common.api.BookFacade" ref="bookFacade" /> </beans>
上面的配置文件中指定序列化方式爲hession2
。
下面咱們經過源碼的方式簡單的分析它們的實現原理。下面咱們直接到序列化的核心類org.apache.dubbo.remoting.transport.CodecSupport
咱們看其中的反序列化方法deserialize
:
public static ObjectInput deserialize(URL url, InputStream is, byte proto) throws IOException { //獲取序列化對象 Serialization s = getSerialization(url, proto); return s.deserialize(url, is); }
咱們繼續看看getSerialization
方法:
public static Serialization getSerialization(URL url, Byte id) throws IOException { //經過協議查找Serialization對象 Serialization serialization = getSerializationById(id); String serializationName = url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION); //... return serialization; }
上面查找經過 SPI 註冊的全部序列化方式。咱們接着deserialize
方法看,這裏咱們以 Java JDK 提供的序列化方式爲例:
public ObjectInput deserialize(URL url, InputStream is) throws IOException { return new JavaObjectInput(is); }
能夠看到這了經過 JDK 提供的 JavaObjectInput
對象包裝數據流。 其餘的序列化方式也是相似,小夥伴能夠自行分析。
在本小節中咱們主要學習了 Dubbo 序列化,同時咱們也分析了 Dubbo 中序列化的實現原理。其底層的實現原理就是利用咱們的序列化和反序列化框架對數據對象進行操做,同時咱們也介紹了當前針對 Java 序列化性能比較高的兩種方式,分別是:Kryo 和 FST。
本節課程的重點以下:
我的從事金融行業,就任過易極付、思建科技、某網約車平臺等重慶一流技術團隊,目前就任於某銀行負責統一支付系統建設。自身對金融行業有強烈的愛好。同時也實踐大數據、數據存儲、自動化集成和部署、分佈式微服務、響應式編程、人工智能等領域。同時也熱衷於技術分享創立公衆號和博客站點對知識體系進行分享。關注公衆號: 青年IT男 獲取最新技術文章推送!
博客地址: http://youngitman.tech
微信公衆號: