我們在接下來會開始講網路通訊相關的內容了。既然是網路通訊,那必然會涉及到序列化的相關技術。
下面是 ccx-rpc
序列化器的介面定義。
/**
* 序列化器
*/
public interface Serializer {
/**
* 序列化
*
* @param object 要序列化的物件
* @return 位元組陣列
*/
byte[] serialize(Object object);
/**
* 反序列化
*
* @param bytes 位元組陣列
* @param clazz 要反序列化的類
* @param <T> 型別
* @return 反序列化的物件
*/
<T> T deserialize(byte[] bytes, Class<T> clazz);
}
介面只包含序列化、反序列化兩個最基礎的方法。不同的序列化器只需要實現這個介面即可,再配合 SPI
就可以使用了。
下面是 ccx-rpc
的一小段反序列化程式碼:
// 獲取序列化型別
SerializeType serializeType = SerializeType.fromValue(codec);
// 獲取序列化器
Serializer serializer = ExtensionLoader.getLoader(Serializer.class).getExtension(serializeType.getName());
// 根據訊息型別選擇反序列化的 Class
Class<?> clazz = messageType == MessageType.REQUEST.getValue() ? RpcRequest.class : RpcResponse.class;
// 進行反序列化
Object object = serializer.deserialize(decompressedBytes, clazz);
序列化演算法有多種多樣,各有千秋,我們需要結合自己的業務,選擇合適的序列化演算法。
序列化演算法的選擇通常有下列一些常用的指標:
- 通用性:是否跨語言,跨平臺。如果 RPC 呼叫涉及到其他語言、平臺,這個指標不可忽視。
- 效能:通常指解析速度、序列化後的大小。序列化後的資料一般用於儲存或網路傳輸,其大小是一個很重要的指標;解析的速度無需多言,當然是越快越好。
- 可擴充套件性:系統升級不可避免,某一實體的屬性變更,會不會導致反序列化異常,也應該納入序列化演算法的考量範圍。
- 易用性:API 使用是否複雜,會影響開發效率。
下面我們來看一下常見的序列化演算法。
常見序列化演算法
1. Java 序列化
Java 序列化大家都很熟悉了,使用起來也不算複雜。先實現 Serializable
,生成序列號 serialVersionUID
,最後呼叫java.io.ObjectOutputStream
的 writeObject()
/ readObject()
進行序列化與反序列化。
說實話,Java 序列化雖然知道,但是還沒真正去用過,這個使用步驟還是臨時搜的。。。
Java 序列化有個致命缺點:那就是不跨語言,而且效能也不太行。所以 Java 序列化很少人用,也成為了我們最熟悉的陌生人。
2. FastJson
FastJson
是阿里開源的 JSON
解析庫。正如其名,“快”是其主要賣點。從官方的測試結果來看,FastJson
確實是最快的,比 Jackson
快 20% 左右,但是近幾年 FastJson
的安全漏洞比較多,而且版本升級可能會存在較大的相容問題,所以在選擇的時候,還是需要謹慎一些。
JSON
的優點就是可讀性高,但是其序列化結果的體積比較大。
3. Jackson
Jackson
相對 FastJson
的功能比較多,安全漏洞也比較少,社群活躍。雖然效能相對於 Jackson
稍差,但是用著安心。
但是其序列化結果的體積比較大,對 RPC 框架來說,還是不大適合的。
4. Kryo
Kryo
是一個高效的 Java 序列化/反序列化庫,其特點是 API 程式碼簡單,序列化速度快,並且序列化之後得到的資料比較小。
優點:介面易用、解析快、體積小
缺點:只支援 Java、增刪欄位會異常
5. Hessian
Hessian
是一種支援動態型別、跨語言的序列化協議,Java 物件序列化的二進位制流可以被其他語言使用。
優點:介面易用、解析快、支援多語言
缺點:異常機制不完善,提示資訊不足
6. Protobuf
Google 公司開發的一套靈活、高效、自動化的、用於對結構化資料進行序列化的協議。相比於常用的 JSON
格式,Protobuf
有更高的轉化效率,時間效率和空間效率都是 JSON
的 5 倍左右。Protobuf
可用於通訊協議、資料儲存等領域,它本身是語言無關、平臺無關、可擴充套件的序列化結構資料格式。目前 Protobuf
提供了 C++
、Java
、Python
、Go
等多種語言的 API。
優點:解析快、體積小、支援多語言。
缺點:需要先定義 proto
結構,使用相對麻煩,不過 Java 可以使用 Protostuff
解決這個問題。
總結
在上文,我們介紹了序列化器的定義,很簡單,只有序列化,反序列化兩個方法。
然後,介紹了常見的序列化演算法,例如Java 序列化、FastJson、Jackson、Kryo、Hessian、Protobuf 等。這些演算法各有優缺點,大家在使用時,可以結合自己的業務情況進行選擇。
ccx-rpc 程式碼已經開源
Github:https://github.com/chenchuxin/ccx-rpc
Gitee:https://gitee.com/imccx/ccx-rpc