grpc.io
gRPC 介紹
gRPC 和 protocol buffers 介紹
- gRPC 可以使用 protocol buffers 當作兩邊的 Interface Definition Language (IDL, 介面描述語言) 和底層的訊息交換格式.
概觀
- 在 gRPC, client app 可以直接呼叫不同機器上 server app 的 method, 彷彿就是一個 local object, 讓你更容易建立出分散式的 app 和 services. 如同很多 RPC 系統, gRPC 的基礎是圍繞在
定義一個 service, 指定可以遠端被呼叫的 method, 與其參數和回傳型別. 在 server 端, server 實作這個 interface, 並運行一個 gRPC server 處理 client 的呼叫. 在 client 端, client 有一個 stub (在某些語言中, 就稱作 client), 他提供和 server 一樣的 methods.

- gRPC clients 和 servers 可以在多樣的環境中運行, 並彼此溝通 - 從 Google 的 servers 到 你自己的桌機 - 而且能以 gRPC 支援的語言寫出來. 所以, 舉例來說, 你能以 Java 簡單地建立一個 gRPC server, 而 clients 則用 Go, Python 或 Ruby. 此外, 最新的 Google APIs 會有他們 interfaces 的 gRPC 版本, 讓你輕鬆將 Google 功能建置在你的 app 裡面.
使用 Protocol Buffers
- gRPC 預設使用 Protocol Buffers, 他是 Google 成熟的 open source, 用於 serializing structured data(序列化具結構的資料) 的機制, 雖然也是可以用其他種資料格式, 像是 JSON.
- 當使用 protocol buffers 時, 第一步是為你要序列化的資料, 在一個 proto 檔 中定義出結構: 這是一個普通的 text 檔, 帶有一個
.proto 副檔名. Protocol buffer 的資料的結構為 message, 而每則訊息都是一個微小的資訊邏輯紀錄, 內含一串連續的 name-value pairs, 稱作 fields:
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}
- 然後, 一旦指定你的資料結構, 使用 protocol buffer compiler
proroc 從你的 proto 定義中, 產生你偏愛語言的 data access classes. 這些提供了簡單的 accessors, 每個 field 像是 name(), 每個 method 像是 set_name(), 再將整個結構 serialize 到 raw bytes, 或從 raw bytes 中將整個結構 parse 出來. 所以, 舉例來說, 如果你選的語言是 C++, 在上述的範例上運行 compiler, 會產生一個叫做 Person 的 class. 然後你可以在你的 app 使用這個 class, 對 Person 的 protocol buffer messages 做 populate, serialize 以及 retrieve.
- 你在普通的 proto 檔中, 以 RPC method 參數和回傳型別, 定義 gRPC:
// greeter service 的定義.
service Greeter {
// 送出一則 greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// request message 內含用戶名稱.
message HelloRequest {
string name = 1;
}
// response message 內含 greetings
message HelloReply {
string message = 1;
}
- gRPC 使用一個特殊的 gRPC plugin,
protoc 從你的 proto 檔中產生出程式碼: 你將得到產出的 gRPC client 和 server 的程式碼, 以及正規的 protocol buffer 程式碼, 用來 populating, serializing 和 retrieving 你的 message types.
Protocol buffer 版本
- 雖然 protocol buffers 已提供 open source 給用戶一段時間, 大部分的範例使用 protocol buffers 版本 3 (proto3), 具備稍微簡化的語法, 和一些好用的新功能, 並支援更多語言.
- 一般來說, 雖然你可以使用 proto2 (目前預設的 protocol buffers 版本), 但我們建議你一起使用 proto3 的 gRPC, 因為他讓你使用完整 gRPC 所支援的語言, 也能避免相容性問題, 像是 proto2 clients 與 proto3 servers 或 反過來, 的溝通問題.
核心概念, 架構 和 lifecycle
介紹 gRPC 的關鍵概念, 並概觀 gRPC 的架構 和 RPC lifecycle .
概觀
Service 定義
- 像是許多 RPC 系統一樣, gRPC 的基礎是圍繞著
定義一個 service, 指定能被呼叫的 methods, 以及其參數和回傳型別. gRPC 預設使用 protocol buffers 當作 Interface Definition Language (IDL, 介面描述語言), 用來描述 service 介面 和 payload messages 的結構.
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
- gRPC 讓你定義四種 service method:
- Unary RPCs 是 client 將單一 request 送到 server 並取回單一 response, 就像是一個正常的 function call.
rpc SayHello(HelloRequest) returns (HelloResponse);
- Server streaming RPCs 是 clients 將單一 request 送到 server 並取回一段 stream, 並讀取一連串的 messages. client 從回傳的 stream 中讀取, 直到沒有 messages. gRPC 保證一筆個別的 RPC call 之間的 messages 順序.
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
- Client streaming RPCs 是 clients 寫入一連串 messages 並送到 server, server 再使用提供的 stream. 一旦 client 已完成寫入 messages, 等到 server 讀取並回傳其 response. gRPC 保證一筆個別的 RPC call 之間的 messages 順序.
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
- Bidirectional streaming RPCs 是兩邊都使用 read-write stream 送出一連串 messages. 兩個 streams 各自獨立操作, 所以 clients 和 servers 能以他們想要的任何順序讀取和寫入: 舉例來說, server 在寫入他的 responses 前, 會等到收完所有 client 的 messages, 或是他可以交替讀取一則 message 然後寫入一則 message, 或是其他讀取和寫入的組合. 每個 stream 的 messages 順序會保留住.
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
使用 API
- 從一個
.proto 檔中的 service 定義開始, gRPC 提供 protocol buffer compiler plugins, 他產生 client 和 server 端的程式碼. gRPC 用戶通常在 client 端呼叫這些 APIs, 並在 server 端實作對應的 API.
- 在 server 端, server 實作出由 service 宣告的 methods, 並運行一個 gRPC server 處理 client 呼叫. gRPC 的基礎設施將進來的request 解碼, 執行 service methods, 和將 service responses 編碼.
- 在 client 端, client 有一個 local object, 稱作 stub (對某些語言來說, 偏好的詞是 client), 他實作出與 service 相同的 methods. 然後 client 就可以在 local object 上呼叫那些 methods, 將呼叫的參數包裝成適當的 protocol buffer message type - gRPC 會看管要送到 server 的 request(s), 並回傳 server 的 protocol buffer response(s).
Synchronous vs. asynchronous
- Synchronous RPC 的呼叫 (block 直到有一個 response 從 server 抵達), 是最接近 RPC 渴望的一個 procedure call. 另一方面, 網路本質上是 asynchronous, 並且在很多情境中, 能夠在不會 block 目前 thread 的前提下啟動 RPCs 是很有幫助的.
RPC lifecycle
Unary RPC
- 先研究最簡單的 RPC 類型, 是 client 將單一 request 送出並取回單一 response.
- 一旦 client 呼叫一個 stub method, server 會被通知 RPC 已經被呼叫, 帶著這次呼叫的
client metadata, method 名, 和 指定的 deadline(如果可以用).
- 然後 server 無論是直接送回他自己初始的 metadata (必須在任何 response 以前送出), 還是等待 client 的 request message.
- 一旦 server 有了 client 的 request message, 他會做好
create 與 populate 一個 response 所需要的一切工作. 然後 response 就被回傳 (如果成功) 到 client, 並帶著 status details (status code 和 status message) 和 跟在後面的 metadata.
- 如果 response status 是 OK, client 得到 response, 也就是 client 端的呼叫完畢.
Server streaming RPC
一個 server-streaming RPC 和 一個 unary RPC 類似, 除了 server 回傳一個 messages stream 對應到 client 的 request. 在送出他所有的 message 後, server 的 status details (status code 和 status message) 和 跟在後面的 metadata, 會被送到 client. 這會在 server 端完成處理流程. 一旦 client 有了所有 server 的 message, client 的呼叫就完畢了.
Client Streaming RPC
一個 client-streaming RPC 和 一個 unary RPC 類似, 除了 client 送出一個 messages stream 到 server, 而不是單一 message. 然後 server 回應單一 message (與其 status details 和 跟在後面的 metadata 一起), 通常但不一定, 是在收到所有 client 的 messages 後回應.
Bidirectional streaming RPC
- 在一個 bidirectional streaming RPC 中, 會因
client 呼叫 method 和 server 收到 client 的 metadata, method 名, deadline 而初始化. server 可以選擇送回他初始的 metadata 或 等待 client 開始 streaming messages.
- Client 和 server 端的 stream 處理是由 app 指定. 因為兩個 streams 是獨立的, client 和 server 能以任何順序讀取和寫入 messages, 或是 server 和 client 可以玩 "ping-pong" - server 得到一個 request, 然後送回一個 response, 然後 client 送另一個由這次 response 而定的 request, 等等.
Deadlines/Timeouts
- gRPC 允許 clients 指定願意等待一個 RPC 多久, 不然就終止並回傳一個
DEADLINE_ECEEDED error. 在 server 端, server 可以查詢特定的 RPC 是否 timed out, 或是還剩多久 RPC 可以完畢.
- 要指定 deadline 還是 timeout 是取決於語言: 有些語言的 APIs 對 timeouts (時間長短) 有效, 有些語言的 APIs 對 deadline (固定的時間點) 有效, 且可能有預設 deadline.
RPC 終止
- 在 gRPC, client 和 server 都會做出獨立, local, 呼叫是否成功的決定, 他們的結論可能互不相符. 這意旨, 舉例來說, 你會有一個 RPC 在 server 端成功完成 ("我已經送出我所有的 responses!") 但在 client 端失敗 ("responses 在我的 deadline 後才抵達!"). 對 server 來說, 他也可能決定在 client 送出他所有的 requests 前完畢呼叫.
取消一個 RPC
- 無論 client 還是 server 可以在任何時間取消一個 RPC. 一個 cancellation 會立即終止 RPC, 這樣就沒有進一步的工作可以達成.
在 cancellation 前的改動不能 rolled back.
Metadata
- Metadata 是關於一個特定 RPC 呼叫的資訊, 是一列 key-value pairs 格式, keys 是 strings 而 values 通常是 strings, 但可以是 binary data. Metadata 對 gRPC 自己並不透明 - 他讓 client 提供呼叫到 server 有關的資訊, 反之亦然.
- 存取 metatdata 取決於語言.
Channels
- 一個 gRPC channel 提供一個連線, 在指定的 host 和 port, 連到 gRPC server. 當創建一個 client stub 時會使用到. Clients 可以指定 channel 的參數, 修改 gRPC 的預設行為, 像是切換 message compression 開關. channel 會有狀態, 包括
connected 和 idle.
gRPC 介紹
概觀
定義一個 service,指定可以遠端被呼叫的 method, 與其參數和回傳型別. 在 server 端, server 實作這個 interface, 並運行一個 gRPC server 處理 client 的呼叫. 在 client 端, client 有一個 stub (在某些語言中, 就稱作 client), 他提供和 server 一樣的 methods.使用 Protocol Buffers
.proto副檔名. Protocol buffer 的資料的結構為 message, 而每則訊息都是一個微小的資訊邏輯紀錄, 內含一串連續的 name-value pairs, 稱作 fields:proroc從你的 proto 定義中, 產生你偏愛語言的 data access classes. 這些提供了簡單的 accessors, 每個 field 像是name(), 每個 method 像是set_name(), 再將整個結構 serialize 到 raw bytes, 或從 raw bytes 中將整個結構 parse 出來. 所以, 舉例來說, 如果你選的語言是 C++, 在上述的範例上運行 compiler, 會產生一個叫做Person的 class. 然後你可以在你的 app 使用這個 class, 對Person的 protocol buffer messages 做 populate, serialize 以及 retrieve.protoc從你的 proto 檔中產生出程式碼: 你將得到產出的 gRPC client 和 server 的程式碼, 以及正規的 protocol buffer 程式碼, 用來 populating, serializing 和 retrieving 你的 message types.Protocol buffer 版本
核心概念, 架構 和 lifecycle
概觀
Service 定義
定義一個 service,指定能被呼叫的 methods, 以及其參數和回傳型別. gRPC 預設使用 protocol buffers 當作 Interface Definition Language (IDL, 介面描述語言), 用來描述 service 介面 和 payload messages 的結構.使用 API
.proto檔中的 service 定義開始, gRPC 提供 protocol buffer compiler plugins, 他產生 client 和 server 端的程式碼. gRPC 用戶通常在 client 端呼叫這些 APIs, 並在 server 端實作對應的 API.Synchronous vs. asynchronous
RPC lifecycle
Unary RPC
client metadata,method 名, 和指定的 deadline(如果可以用).create 與 populate 一個 response所需要的一切工作. 然後 response 就被回傳 (如果成功) 到 client, 並帶著status details (status code 和 status message)和跟在後面的 metadata.Server streaming RPC
一個 server-streaming RPC和一個 unary RPC類似, 除了 server 回傳一個 messages stream 對應到 client 的 request. 在送出他所有的 message 後, server 的status details (status code 和 status message)和跟在後面的 metadata, 會被送到 client. 這會在 server 端完成處理流程. 一旦 client 有了所有 server 的 message, client 的呼叫就完畢了.Client Streaming RPC
一個 client-streaming RPC和一個 unary RPC類似, 除了 client 送出一個 messages stream 到 server, 而不是單一 message. 然後 server 回應單一 message (與其status details和跟在後面的 metadata一起), 通常但不一定, 是在收到所有 client 的 messages 後回應.Bidirectional streaming RPC
client 呼叫 method和server 收到 client 的 metadata, method 名, deadline而初始化. server 可以選擇送回他初始的 metadata 或 等待 client 開始 streaming messages.Deadlines/Timeouts
DEADLINE_ECEEDEDerror. 在 server 端, server 可以查詢特定的 RPC 是否 timed out, 或是還剩多久 RPC 可以完畢.RPC 終止
取消一個 RPC
Metadata
Channels
connected和idle.