本篇为【写给go开发者的gRPC教程系列】第一篇
第一篇:protobuf基础 👈
第二篇:通信模式
第三篇:拦截器
第四篇:错误处理
gRPC
是谷歌开源的一款高性能、支持多种开发语言的服务框架,对于一个rpc我们关注如下几方面:
序列化协议。gRPC
使用protobuf
,首先使用protobuf定义服务,然后使用这个文件来生成客户端和服务端的代码。因为pb是跨语言的,因此即使服务端和客户端语言并不一致也是可以互相序列化和反序列化的
网络传输层。gRPC使用http2.0
协议,http2.0
相比于HTTP 1.x
,大幅度的提升了 web 性能。
Protobuf IDL
所谓序列化通俗来说就是把内存的一段数据转化成二进制并存储或者通过网络传输,而读取磁盘或另一端收到后可以在内存中重建这段数据
1、protobuf
协议是跨语言跨平台的序列化协议。
2、protobuf
本身并不是和gRPC
绑定的。它也可以被用于非RPC场景,如存储等
json
、 xml
都是一种序列化的方式,只是他们不需要提前预定义idl,且具备可读性,当然他们传输的体积也因此较大,可以说是各有优劣
所以先来介绍下protobuf
的idl怎么写。protobuf
最新版本为proto3
,在这里你可以看到详细的文档说明:https://protobuf.dev/programming-guides/proto3/
定义消息类型
protobuf
里最基本的类型就是message
,每一个messgae
都会有一个或者多个字段(field
),其中字段包含如下元素
-
类型:类型不仅可以是标量类型(
int
、string
等),也可以是复合类型(enum
等),也可以是其他message
-
字段名:字段名比较推荐的是使用下划线/分隔名称
-
字段编号:一个messgae内每一个字段编号都必须唯一的,在编码后其实传递的是这个编号而不是字段名
-
字段规则:消息字段可以是以下字段之一
-
singular
:格式正确的消息可以有零个或一个字段(但不能超过一个)。使用 proto3 语法时,如果未为给定字段指定其他字段规则,则这是默认字段规则 -
optional
:与singular
相同,不过您可以检查该值是否明确设置 -
repeated
:在格式正确的消息中,此字段类型可以重复零次或多次。系统会保留重复值的顺序 -
map
:这是一个成对的键值对字段
-
-
保留字段:为了避免再次使用到已移除的字段可以设定保留字段。如果任何未来用户尝试使用这些字段标识符,编译器就会报错
标量值类
标量类型会涉及到不同语言和编码方式,后续有机会深入讲
.proto Type | Go Type | Notes |
---|---|---|
double | float64 | |
float | float32 | |
int32 | int32 | 使用可变长度的编码。对负数的编码效率低下 - 如果您的字段可能包含负值,请改用 sint32。 |
int64 | int64 | 使用可变长度的编码。对负数的编码效率低下 - 如果字段可能有负值,请改用 sint64。 |
uint32 | uint32 | 使用可变长度的编码。 |
uint64 | uint64 | 使用可变长度的编码。 |
sint32 | int32 | 使用可变长度的编码。有符号整数值。与常规 int32 相比,这些函数可以更高效地对负数进行编码。 |
sint64 | int64 | 使用可变长度的编码。有符号整数值。与常规 int64 相比,这些函数可以更高效地对负数进行编码。 |
fixed32 | uint32 | 始终为 4 个字节。如果值通常大于 2^28,则比 uint32 更高效。 |
fixed64 | uint64 | 始终为 8 个字节。如果值通常大于 2^56,则比 uint64 更高效。 |
sfixed32 | int32 | 始终为 4 个字节。 |
sfixed64 | int64 | 始终为 8 个字节。 |
bool | bool | |
string | string | 字符串必须始终包含 UTF-8 编码或 7 位 ASCII 文本,并且长度不得超过 232。 |
bytes | []byte | 可以包含任意长度的 2^32 字节。 |
复合类型
数组
message SearchResponse {
repeated Result results = 1;
}
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
}
枚举
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
Corpus corpus