1 通信模型
設計宗旨
- 覆蓋gRPC的4種通信模型。
- 方法名和參數名不引入任何業務因素,避免額外思考,專注技術本身。
方法定義
- Unary RPC:
talk
- Server streaming RPC:
talkOneAnswerMore
- Client streaming RPC:
talkMoreAnswerOne
- Bidirectional streaming RPC:
talkBidirectional
protobuf定義
service LandingService {
//Unary RPC
rpc talk (TalkRequest) returns (TalkResponse) {
}
//Server streaming RPC
rpc talkOneAnswerMore (TalkRequest) returns (stream TalkResponse) {
}
//Client streaming RPC with random & sleep
rpc talkMoreAnswerOne (stream TalkRequest) returns (TalkResponse) {
}
//Bidirectional streaming RPC
rpc talkBidirectional (stream TalkRequest) returns (stream TalkResponse) {
}
}
方法設計
- 簡單的主線邏輯:服務端將請求參數中的
data
字段的值作為hello
數組的下標,並將相應的值返回給客戶端。 -
簡化請求和響應形式,避免使用多個類型來區分單複數:
- 請求統一使用字符串,複數形式使用逗號分開。
- 響應統一使用數組,單數時數組只包含一條結果。
- 客戶端和服務端都傳遞編程語言信息,以{lang}值顯式展示流量管理的配置效果。
2 協議設計
設計宗旨
- 請求參數足夠簡單,以方便調試,但要包含足夠的信息。
- 響應參數的數據類型要儘可能覆蓋全面,以實現演示的目的。
請求協議
只使用字符串類型,包含請求hello數組的下標值和編程語言信息。
message TalkRequest {
//language index
string data = 1;
//clientside language
string meta = 2;
}
響應協議
- 響應只包含兩個字段,整數類型的狀態碼和
TalkResult
類型的數組。 -
TalkResult
類型內部,分別定義了長整型、枚舉類型、鍵值類型(k/v的泛型為字符串)。
message TalkResponse {
int32 status = 1;
repeated TalkResult results = 2;
}
message TalkResult {
//timestamp
int64 id = 1;
//enum
ResultType type = 2;
// result uuid
// language index
// data hello
// meta serverside language (It's not good here,
// but ok since I feel like to keep the response)
map<string, string> kv = 3;
}
enum ResultType {
OK = 0;
FAIL = 1;
}
3 實現要點
環境變量
我們需要為GRPC的client提供一個變量GRC_SERVER
,在本地開發調試時其值為localhost
,在POD啟動時動態定義為GRPC Service的值,以便client調用。
隨機數
在Client streaming和Bidirectional streaming兩種通信方式下,客戶端需要隨機產生一個整型數值,取值要求在hello數組下標的範圍內。
時間戳
TalkResult.id
是int64
類型的唯一標識,通過時間戳來實現。
UUID
TalkResult.kv[id]
是字符串類型的唯一標識,我們通過UUID來實現。
sleep
在streaming方式下,為了更好地觀察,通過sleep方式設置兩次請求的間隔。