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方式设置两次请求的间隔。