更新時間:2021-09-22 11:22:38 來源:動力節點 瀏覽1265次
在Java開發工具當中,Java序列化工具是比較常用的,而且種類也有不少,下面小編就來做個對比:
Binary Formats & language-specific Ones
Javabuiltin (Java native), javamanual (根據成員變量類型手動編寫), fstserliazation , kryo
二進制格式-通用語言-非特定 Ones
protobuf (Google) , Thrift (Facebook) , Avrogeneric, Hessian
JSON 格式
Jackson、Gson、Fastjson
Json-like:
CKS (Textual json-like format), BSON (json-like format with extended datatypes), Jacksonbson, MongoDB
基于 xml 的格式
Xmlxstream
Java序列化工具大致可以分為以上幾類,簡單概括分為二進制二進制和文本格式(JSON、XML)兩大類。
在速度的比較上,一般有以下規律:
Binary > textual
Language-specific > Language-unspecific
在 textual 中,XML 冗余度低于 JSON,這使得它在文本序列化上更加 bson 和更加復雜JSON,框架選擇更豐富、更優秀。下面重點介紹下Kryo、Fast-serialiation、Fastjson、Protocol-buffer
互聯網公司使用Protobuf、Thrift、Avro等成熟的序列化解決方案來構建RPC框架是一個經過驗證的解決方案。
(1)Java Native 序列化工具
Java本身提供的序列化工具基本上可以在大部分場景下對任務進行序列化,本文的序列化機制是非常詳細的講解(7820018),值得一讀。Java自帶的序列化工具在序列化過程中不僅需要記錄對象的完整類名,還需要記錄類的定義,包括所有其他引用的類,尤其是在非常大的開銷下序列化單個對象時. 因為Java的序列化機制記錄了所有的元數據,修改類的包名時反序列化是錯誤的。Java自序列化工具的性能問題總結如下:
單個對象的序列化是與所有成員變量(instsnce 變量)一起遞歸序列化,這是一種默認機制,很容易導致不必要的序列化開銷。
序列化和反序列化的過程需要使用這種機制,使用反射機制遞歸合并所有成員變量的信息,如果沒有定義自己的serialversionuid,那么對象和其他變量必須自己產生一個。上述過程成本很高。
使用默認的序列化機制,記錄所有序列化類定義的完整信息,包括所有包名、父類信息和成員變量
(2)優化的Java序列化工具
Kryo
Kryo基于Java原生序列化機制的一些問題,做了很多優化,提供了很多序列化器,甚至封裝了不安全序列化的類型,以及更多關于不安全序列化方法的類型,請注意這里, jdk1.7后默認關閉Unsafe Class(Sun.misc.Unsafe)包。更多 Kryo 參考 Kryo 維基介紹。
Fast-serialization
fst-serialozation是一個比較新的序列化工具,雖然從2-1的kryo的速度評價還有一些差距,但是根據我在現場的生產環境測試,kryo的效果幾乎一致, 可以即時反序列化內容和渲染
(3)JSON
好的 JSON 解析工具還是比較好的,有些 JSON 解析工具甚至比一些二進制序列化方法還要快。
(4)協議緩沖區
Protocol buffers 是一種序列化結構化數據的技術,支持 C++、Java、Python 等多種語言,可用于持久化數據或序列化要通過網絡傳輸的數據。與其他一些 XML 技術相比,這種技術的一個明顯特點是它更節省空間(存儲在二進制流中)、速度更快、更靈活。
另外,PROTOBUF 支持的數據類型比較少,不支持常量類型。由于其設計理念純粹是表示層協議(Presentation layer),目前還沒有專門支持PROTOBUF的RPC框架。
(5)節儉
Thrift 是 Facebook 開源的高性能、輕量級 RPC 服務框架,旨在滿足當今大數據量、分布式、跨語言、跨平臺數據通信的需求。然而,Thrift 不僅僅是一個序列化協議,而是一個 RPC 框架。與 JSON 和 XML 相比,thrift 在空間成本和解析性能上有很大的提升,對于性能要求很高的分布式系統來說是一個很好的 RPC 解決方案,但是因為 thrift 框架內嵌了 thrift 序列化,所以 thrift 框架本身并沒有透露序列化和反序列化接口,這使得它很難與其他傳輸層協議(例如 HTTP)一起使用。
(6)阿夫羅
Avro解析性能高,序列化后的數據非常簡潔,更適合高性能的序列化服務。
Avro 提供了兩種序列化格式:JSON 格式或二進制格式。二進制格式在空間開銷和解析性能上可以與protobuf相媲美,JSON 格式有助于測試階段的調試。Avro 支持非常豐富的數據類型,包括 C++ 語言中的聯合類型。AVRO支持JSON格式的IDL和類似于thrift和protobuf的IDL(實驗階段),可以相互轉換。模式可以在傳輸數據的同時發送,加上 JSON 的自描述屬性,這使得 Avro 非常適合動態類型語言。Avro通常在文件持久化時和schema一起存儲,因此Avro序列化文件本身具有自描述屬性,因此非常適合hive、pig和MapReduce的數據格式持久化。對于不同版本的schema,在進行RPC調用時,服務端和客戶端可以在握手階段相互確認schema,
Kryoregister、FST、Kryo、Gson、Fastjson、JDK
(1)JDK
public static byte[] serialize(Object obj) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); byte[] bs = baos.toByteArray(); baos.close(); oos.close(); return bs; } catch (IOException e) { throw new RuntimeException(e); }}public static Object deserialize(byte[] bits) { try { ByteArrayInputStream bais = new ByteArrayInputStream(bits); ObjectInputStream ois = new ObjectInputStream(bais); Object obj = ois.readObject(); bais.close(); ois.close(); return obj; } catch (Exception e) { throw new RuntimeException(e); }}
(2)Fastjson
JSON 庫中涉及的最基本功能之一是序列化和反序列化。Fastjson 支持 Java bean 的直接序列化。使用 Com.alibaba.fastjson.JSON 類進行序列化和反序列化。
public static String serialize(Object obj){ String json = JSON.toJSONString(obj); return json;}public static Object deserialize(String json, Class<?> clazz){ Object obj = JSON.parseObject(json, clazz); return obj;}
(3)第一時間
FST Fast-serialization是一個重新實現的Java快速對象序列化開發包。序列化速度更快(2-10倍),體積更小,兼容JDK原生序列化。
Java Fast Serialization 庫FST 2.0 版本已經發布,包名更改為不平滑升級。另外,出于穩定性考慮,官方建議使用最新的1.58版本。
static FSTConfiguration configuration = FSTConfiguration .createDefaultConfiguration();public static byte[] serialize(Object obj){ return configuration.asByteArray((Serializable)obj);}public static Object deserialize(byte[] sec){ return configuration.asObject(sec);}
(4)Gson
這以 JSON 格式使用,并使用 Google Gson 進行轉義。
static Gson gson = new Gson();public static String serialize(Object obj){ String json = gson.toJson(obj); return json;}public static Object deserialize(String json, Class<?> clazz){ Object obj = gson.fromJson(json, clazz); return obj;}
對于原本采用Java Native序列化方案的系統,Kryo Fst-serializer是Java Native序列化方案的一個很好的替代方案,不僅體現了重新編程的簡單性,而且在速度和性能上也有很大的提升,尤其是Fst -serializer,只是替換了Output/inputstream,升級的性能也很可觀,工具剛出來,穩定性需要更多測試。
如果程序本身是JSON格式的序列化,可以考慮引入一個優秀的JSON解析庫,General Service端Jackson就是一個流行的解析庫。
Protobuffer 更多是消息交換格式的 XML 替代語言,盡可能快,但是編程需要定義消息格式,關于成員變量,業務復雜 javabean 成本比較復雜,對于穩定的現有系統,整體成本更高。
想了解更多Java技術,不妨關注動力節點Java在線學習,教程針對沒有任何Java基礎的讀者學習,讓你從入門到精通,主要介紹了一些Java基礎的核心知識,讓同學們更好更方便的學習和了解Java編程,感興趣的同學可以關注一下。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習