1. 程式人生 > >gRPC proto3語法

gRPC proto3語法

公司專案使用了gRPC, 剛從java轉go的我實在是搞不懂。百度了參考各種資料,在這裡做個記錄。

參考:https://blog.csdn.net/carson_ho/article/details/70568606

定義:

 一種  結構化資料 的資料儲存格式。(類似於xml, json)

作用

通過將  結構化的資料  進行序列化(序列化),從而實現 資料儲存/rpc資料交換 的功能

序列化:將資料結構或物件 轉換成 二進位制的  過程

飯序列化:將在序列化過程中所生成的二進位制串  轉換成  資料結構或物件 的過程。

特點

相對於xml,json,protocol buffer有如下特點:


應用場景

傳輸資料量大 & 網路環境不穩定的資料儲存 、rpc資料交換的需求場景。

序列化原理解析:

序列化本質:對資料進行編碼 + 儲存

1. 序列化速度快:

   編碼/解碼 方式簡單(只需簡單的數學運算= 位移等)

  採用pb自身的框架程式碼 和編譯器共同完成

2. 序列化後體積小(資料壓縮效果好)

  採用了獨特的編碼方式,如Varint, Zigzag等

  採用T - L - V 的資料儲存方式,

  • 即 Tag - Length - Value標識 - 長度 - 欄位值 儲存方式,減少了分隔符的使用,資料儲存得緊湊

使用步驟:

1. 環境配置

1.1 下載protocol buffer

1.2 安裝HOMEBREW

1.3 安裝protocol buffer 

2. 構建protocol buffer訊息物件模型

2.1 通過protocol buffer語法,描述需要儲存的資料結構:.proto檔案

2.2 通過protocol buffer 編譯器,編譯.proto檔案(生成對應平臺的程式碼檔案)

proto3語法

1.定義訊息型別

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

檔案第一行指定了使用的proto3語法,如果不指定,預設使用proto2.這個語句必須在.proto檔案的非空非註釋的第一行。

可見請求訊息結構體中定義了3個欄位:query,page_number, result_per_page,每個欄位都有名稱和型別。

指定欄位型別:

上面的3個欄位都是值型別,兩個整型和一個字串型別。可以指定欄位的組合型別,包括列舉和其他訊息型別。

分配標識---tag:

訊息請求結構體中每個欄位都有唯一的數字標識,這些標識用來在訊息的二進位制格式中識別你的欄位,並且一旦訊息投入使用,這些標識就不應該再被修改。

標識1-15使用一個位元組編碼,包括數字和欄位型別;標識16-2047使用兩個位元組編碼。所以應該保留1-15,用作出現最頻繁的訊息型別的標識,不要把1-15用完,為以後留點。

可以指定最小的標識數字為1,最大為229 - 1, or 536,870,911,或者536 870 911.不能使用19000-19999之間的數字,是protocol buffers的保留標識。

指定欄位規則:

訊息欄位可以是以下的一種:

1. singular(單個):符合語法規則的訊息包含零個或者一個這樣的欄位(最多一個)

2. repeated(重複):一個欄位在合法的訊息中可以重複出現一定的次數(包括零次).重複出現的值的次序將被保留,在proto3中,重複出現的值型別欄位預設採用壓縮編碼。

新增更多訊息型別:

多個訊息型別可以定義在一個.proto檔案中。這樣在定義多個關聯的訊息的時候很有用,如:

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message SearchResponse {
 ...
}

添加註釋:

message SearchRequest {
  string query = 1;
  int32 page_number = 2;  // Which page number do we want?
  int32 result_per_page = 3;  // Number of results to return per page.
}

編譯.proto檔案

.proto檔案編譯之後,編譯器會為你選擇的語言生成程式碼。在檔案中描述的訊息型別,包括獲取和設定欄位的值,序列化你的訊息到一個輸出流,以及從一個輸入流中轉換出你的訊息。

1.c++,編譯器會為每個.proto檔案生成一個.h和一個.cc的檔案,為每一個給出的訊息型別生成一個類。

2.java,編譯器會生成一個java檔案,其中為每個訊息型別生成一個類,還有特殊的用來建立這些訊息類例項的Builder類。

3.python,會生成一個模組,為每個訊息型別生成一個靜態的描述器,在執行時,和一個metaclass一起使用來建立必要的python資料訪問類。

4.go:為每個訊息型別生成一個.pb.go的檔案

5.ruby:每一個.proto生成一個.rb檔案

6.objective-c :每個.proto生成一個pbobjc.h和一個pbobjc.m檔案

7.c#:每個.proto生成一個.cs檔案

值型別


參考:  https://www.cnblogs.com/lijunhao/p/6169566.html

欄位預設值:

1.string ,預設值是空字串

2.bytes:預設值是空bytes

3. bools 預設值是false

4.numberic  預設值是0

5. enums: 預設值是第一個列舉值(value必須為0)

6.message fields,the field is not set. Its exact value is langauge-dependent. See the generated code guide for details.

7.repeated fields,預設值為empty,通常是一個空list