gRPC介紹
gRPC是一個高性能、開源且通用的RPC框架,它基于HTTP/2標準協議和Protocol Buffers進行數據序列化,支持多種編程語言。
rpc和http區別
- 傳輸協議:RPC可以基于TCP或HTTP協議,而HTTP服務則工作在HTTP協議之上。
- 效率和性能消耗:由于RPC可以使用自定義的TCP協議,請求報文體積可以更小,或者使用HTTP2協議來減少報文體積,從而提高傳輸效率。HTTP在1.1版本中可能包含較多無用信息,而2.0版本則可以簡化封裝,適合作為RPC使用。在性能消耗方面,RPC可以基于Thrift等高效二進制傳輸方式,而HTTP大多使用JSON,可能在字節大小和序列化耗時上更消耗性能。
ProtoBuf和json 對比
ProtoBuf在時間和空間效率上均優于JSON,具有顯著的性能優勢。
從時間效率上看,當處理的數據交換次數在2千以上時,ProtoBuf的編碼和解碼性能就已經比JSON高出很多。隨著數據交換次數的增加,這種性能差異會變得更加明顯。特別是在數據交換次數達到10萬以上時,ProtoBuf的編解碼性能遠遠高于JSON。這意味著在高頻率的數據交互場景中,ProtoBuf能夠提供更快的數據處理速度。
從空間效率上看,ProtoBuf的內存占用僅為JSON的三分之一左右。在一項對比測試中,ProtoBuf的內存占用為34,而JSON達到了106,這表明ProtoBuf在內存使用上更為高效。這在資源受限或者需要處理大量數據的場景中尤為重要,因為它可以減少系統資源的消耗。
綜上所述,ProtoBuf在時間和空間效率上都表現出色,尤其是在數據量較大或處理頻繁的場景下,其性能優勢更加突出。這使得ProtoBuf成為了許多高性能數據交換場景的首選格式。
ProtoBuf優點
- 性能優異:ProtoBuf具有較小的數據體積,序列化后的數據大小可以縮小3-10倍。同時,它的序列化速度非常快,比XML和JSON快20-100倍。由于數據體積小,傳輸速度快,因此在帶寬和速度方面會有優化。
- 使用簡便:通過proto編譯器,ProtoBuf可以自動進行序列化和反序列化操作,無需手動編寫代碼。
- 維護成本低:多平臺只需維護一套對象協議文件(.proto),減少了在不同平臺上的維護成本。
- 向后兼容性好:ProtoBuf支持對數據結構進行更新,而不必破壞舊數據格式,因此具有良好的向后兼容性。
- 加密性好:在Http傳輸中,抓包只能看到字節內容,無法直接查看明文信息,提高了數據的安全性。
- 跨平臺、跨語言支持:ProtoBuf支持多種編程語言,包括Java, Python, Objective-C, C++, Dart, Go, Ruby, C#等,并且具有良好的可擴展性。
ProtoBuf的缺點
- 不適合用于對基于文本的標記文檔(如HTML)建模,因為文本不適合描述數據結構。
- 通用性較差:雖然Json和Xml已成為多種行業標準的編寫工具,但ProtoBuf只是Google公司內部的工具,其通用性相對較差。
- 自解耦性差:ProtoBuf以二進制數據流方式存儲,無法直接閱讀,需要通過.proto文件才能了解到數據結構。
- 閱讀性差:生成出來的模型文件是不允許修改的(protoBuf官方建議),如果有新增字段,都必須依賴于.proto文件重新進行生成,導致生成出來的模型無論從可讀性還是易用性上來說都是較差的。
proto文件基礎介紹
Protocol Buffers(簡稱ProtoBuf)是Google開發的一種數據序列化協議,它能夠將結構化數據序列化為二進制格式,用于數據存儲或網絡傳輸。以下是proto文件的基礎介紹:
- 消息定義:在proto文件中,使用message關鍵字定義一個數據結構,這類似于C++中的class、Java中的Class或Go中的struct。消息中承載的數據對應于每個字段,每個字段都有一個名字和類型。
- 字段規則:
- required:表示必填字段,如果這些字段未設置,會導致編解碼異常。
- optional:表示可選字段,對應生成的是指針類型。
- repeated:表示可重復字段,這些字段的值順序會被保留,在Go中通常被定義為切片類型。
- 文件規范:創建proto文件時,應使用全小寫字母命名,多個單詞之間用下劃線連接。例如:lower_snake_case.proto。書寫代碼時應使用2個空格的縮進。注釋可以使用單行注釋(//)或多行注釋(/* */)。
- 語法指定:在文件首行指定該proto文件所采用的語法版本,如syntax = “proto3”;表示使用proto3語法。
- 編解碼原理:ProtoBuf通過Thrift編碼和解碼數據,這是一種緊湊的二進制格式,可以有效地用于網絡傳輸和文件存儲。
以下是一個簡單的文件示例:
syntax = "proto3";message Error {int32 code = 1;string message = 2;}message Request {string id = 1;string data = 2;}message Response {Error error = 1;string result = 2;}service MyService {rpc GetData (Request) returns (Response);}
在上面的示例中,我們定義了一個名為MyService的service,它包含一個名為GetData的rpc方法。該方法接受一個Request類型的參數,并返回一個Response類型的結果。
通過這樣的定義,我們可以使用proto生成對應語言的代碼,以便在客戶端和服務端之間進行RPC通信。客戶端可以調用服務端上的GetData方法,并傳遞一個Request對象作為參數,服務端將返回一個Response對象作為結果。