茶艺师学微服务(准备篇2)
前言
作为茶艺师的我,在了解到了微服务的概念后,自然会浮现这么一个想法:
“比起怎么拆应用,我更不懂的是如何把这些拆完的部件联系在一起(微服务的底层通信),那我是不是该先了解这部分?”
gRPC
有句话是这么说的,“遇事不绝选 gRPC ,绝对不会出错。”
gPRC 是高性能、开源的 RPC (远程过程调用)框架,其特点是
- 高性能 (基于 QUIC 协议 + 利用 HTTP 双向流特性 + 支持流控/压缩)
- 跨语言(能支持主流语言,跨语言调用非常好用,比如 go 能去调 c++ 的)
- 开源(有着活跃的开源社区)
gRPC 为什么能跨语言?
原因就是, gRPC 使用了 IDL 来定义服务端与客户端的之间的通信格式。
IDL ,全名为 interface definition language 接口定义语言,是描述软件组件接口定义的一种计算机语言,是跨平台开发的基础。
gRPC 的 IDL 是在编译过程中生成对应语言的代码,与语言、平台无关。
gRPC 的 IDL :Protobuf
gRPC 的 IDL 选择了 Protobuf 。 Protobuf 是 Google 开发的数据序列化协议,用于高效地序列化和反序列化结构化数据,它被广泛应用于跨平台通信、数据存储和 RPC(远程过程调用)等领域。
简单来说,就是 gRPC 规定了 IDL ,然后找到了 Protobuf 来作为这 IDL 的落地实现。
能被选上的 Protobuf ,自然会有这样的优势:
- 高效性 (序列化、反序列化都很快,而且还能高效压缩,大大降低传输和存储的开销)
- 跨平台、语言无关
- 强大的扩展性 (具有灵活的消息格式定义方式,能很方便的扩展和修改数据结构,还不用对该数据结构进行修改)
- 丰富的 API 支持
Protobuf 的基本原理就是使用二进制的方式进行序列化与反序列化,对应的格式为 JSON(文本格式) 。
Protobuf 语法入门
protobuf 文件的后缀名为.proto
go 语言的 IDE 自带 protobuf ,因此可以直接写。
在文件开头一定要写以下内容:
接着就是关键,消息的定义,看下图:
字段的基本类型有:
- int 族、uint 族和 sint 族
- bytes
- float 和 double
- fixed 族和 sfixed 族
- bool
- string
字段还能支持 map ,数组和 optional(可选的字段),用法看下图:
其中数组 repeated(可重复的),在 go 语言里就会被写成切片。
oneof,用法看下图:
枚举类型 enum ,用法看下图:
【核心】Service 服务的定义,看下图:
可以看到, Service 里的一个 rpc ,都是一个请求配一个回应。
编译 protoful 文件
首先得先安装 protoc ,Windows 下载地址:
GitHub
安装好后接着安装插件:
go installgoogle.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
【注意】记得 GOPATH/bin 目录加入到环境变量,不然插件无法起效
运行命令(照着复制就行了):
protoc `--go_out=. \
`--go_opt=paths=source_relative \
`--go-grpc_out=. \
`--go-grpc_opt=paths=source_relative \
user.proto
其中:
- “-” 在 windows 里面是特殊的字符,要使用 ` 进行转义。
- --go_out =. 的意思是生成代码到当前目录。
- --go_opt=paths=source_relative:这个选项配置了生成的 Go 代码的路径。source_relative 表示相对路径将相对于 .proto 文件的位置计算。
- --go-grpc_out=.:这个选项告诉编译器生成 Go gRPC 的源代码,并将其输出到当前目录(.)。
- --go-grpc_opt=paths=source_relative:这个选项配置了生成的 Go gRPC 代码的路径。source_relative 表示相对路径将相对于 .proto 文件的位置计算。
编译产物
.pd.go 文件是结构体定义的 go 代码。 _grpc.pd.go 文件是 grpc 的代码。
(在对比2中能看到,数组对应着切片,可选的对应着指针,而oneof对应着是接口,在用的时候得断言)
(上图中的 isUser2_Contests ,就是所谓的标记接口,为下面的 User2_Phone 与 User2_Email 提供一个公共类型)
小结
到这里,我试着写了一个简单的 proto 文件,安装好工具编译出对应的 go 代码文件与 gRPC 代码文件。
也算是有点小进度了。