程序員常用的幾種序列化方式,總有一個是你在用的
我們都知道程序在運行的過程中經常需要進行服務間的通信和交互,特別是在當下微服務的架構下,每個系統(tǒng)都會龐大那么為了提高服務間的通信效率以及數據傳輸的性能,我們往往都會將需要傳輸的數據進行序列化,然后再進行傳輸。
什么是序列化
關于序列化相信大家都很了解,在 Java 中我們經常就可以看到很多實體類或者 POJO 都會實現 Serializable 接口,有了解過 Serializable 接口的小伙伴應該都知道,這個接口是一個空接口,只是用來標記的。所謂序列化簡單來說就是在傳輸對象之前將對象轉換成二進制字節(jié)進行傳輸,接收端在收到二進制數據后再反序列化轉化成普通對象。
所以說序列化最終的目的是為了對象可以跨平臺存儲和進行網絡傳輸。之所以需要序列化是因為在網絡傳輸的時候,我們需要經過 IO,而 IO 傳輸支持的就是字節(jié)數組這種格式,所以序列化過后可以更好的傳輸。另外反序列化就是根據字節(jié)數組反向生成對象,是一個逆向過程。
常見的序列化方式
既然知道了什么是序列化,那么接下來我們看看有哪些常見的序列化方式。
JSON
當下最流行的序列化方式無非是 JSON 了,而且 JSON 作為前后端交互使用最廣泛的格式,形式如下。作為最通用的格式,各種語言都支持,并且可以支持復雜的對象。
JSON 作為一個序列化方案,它的優(yōu)點是可讀性很高,跨平臺跨語言支持;但是有個缺點那就是體積較大,很存在很多冗余內容,比如雙引號,花括號。
相信 JSON 大家在工作中使用的肯定會廣泛,阿里提供的 fastjson 包是我們項目中必不可少的一個依賴。
XML
前些年不管是使用 SSM,還是使用 Spring 都會有很多 XML 的配置文件,現在很多被注解代替了,但是 XML 還是支持使用的。另外有一些廣電或者銀卡等老系統(tǒng)里面會有很多基于 XML 的協(xié)議開發(fā)的系統(tǒng)和服務。
阿粉之前做項目就遇到過銀行的項目,里面都是很古老的 XML 協(xié)議,對接起來真是頭疼呀~
通過上面例子我們可以看到,XML 協(xié)議的優(yōu)缺點跟 JSON 類似,優(yōu)點也是可讀性很強,跨平臺跨語言支持,缺點也是體積大,容易內容多。可以看到為了記錄一個字段的值,每個標簽都需要成對存在,過于冗余了。
Protobuf
Protobuf 是谷歌提出的一種序列化協(xié)議,Protobuf 是一種接口定義語言,它與語言和平臺無關。它是一種序列化結構化數據并通過網絡傳輸的方式,使用 Protobuf 傳輸二進制文件,與 JSON 的字符串格式相比,它提高了傳輸速度。
這里提到 Protobuf 是一種接口定義語言,說明也是一種語言,既然是語言那就有自己的關鍵字以及規(guī)則,所以對于Protobuf 協(xié)議,我們需要創(chuàng)建一個后綴為 .proto
message 關鍵字表示定義一個結構體,required 表示必須,optional 表示可選,此外還有字段的名稱和類型。這個原始的 proto 文件是通用的,只要定義一次就好,不管使用哪種語言都可以通過 proto 工具自動生成對應語言的代碼。
比如要生成 Java 代碼,我們可以執(zhí)行下面的命令
protoc --java_out=. demo.proto 就會在指定的目錄下,生成對應的 Demo.java,想生成其他語言的代碼,只需要修改命令執(zhí)行的參數即可,生成的代碼內容會有很多,可以不用管直接使用就行。
我們定義模型的結構一次,然后就可以使用生成的源代碼輕松地使用 Java、Python、Go、Ruby 和 C++ 等各種語言在各種數據流中寫入和讀取結構化數據。
Protobuf 的優(yōu)點主要是性能高,體積小,缺點就是要學習一下特定的關鍵詞以及要下載按照 Protobuf 命令工具。
Thrift
Thrift 也是一種序列化協(xié)議,具體的使用方式跟 Protobuf 類似,只不過 Thrift 是 Facebook 提出來的一種協(xié)議。
Thrift是一種接口描述語言和二進制通訊協(xié)議,原由Facebook于2007年開發(fā),2008年正式提交Apache基金會托管,成為Apache下的開源項目。
Thrift 是一個 RPC 通訊框架,采用自定義的二進制通訊協(xié)議設計。相比于傳統(tǒng)的HTTP協(xié)議,效率更高,傳輸占用帶寬更小。另外,Thrift是跨語言的。Thrift的接口描述文件,通過其編譯器可以生成不同開發(fā)語言的通訊框架。
Thrift 的使用方式跟 Protobuf 類似,也是有一個 .thrift 后綴的文件,然后通過命令生成各種語言的代碼,這里就不演示了。
除了上面提到的四種序列化方式之外,還有 Hessian,JDK 原生等序列化方式,就不一一介紹了。
序列化協(xié)議選擇
前面提到是幾種序列化的協(xié)議方式,那么對于我們平常項目中使用的時候,我們應該如何選擇自己的協(xié)議呢?需要關注哪幾個方面的內容呢?
每個協(xié)議有每個協(xié)議的特點,具體選擇哪種協(xié)議我們要根據實際的場景來選擇,比如說如果是前后端對接,那么自然是 JSON 最合適,應該網頁的交互要求不需要太高,秒級別是可以接受的,所以我們可以更加關注可讀性。但是如果是微服務之間的數據傳輸,那我們就可以選擇 Protobuf 或者 Thrift 這種更高效的協(xié)議來進行傳輸,因為這種場景我們對于協(xié)議序列化的體積和速度都有很高的要求。
總結
今天阿粉給大家介紹了幾種序列化的協(xié)議,相信大家在日常工作中必然會用到,上面提到的協(xié)議你是否都用過呢?歡迎在評論區(qū)留言探討。