gRPC-Go -- #1 总览全局
本系列文章基于 grpc-go v1.67.0
RPC 是什么
RPC,即远程过程调用,是一种通信协议,允许程序调用位于另一台服务器上的函数或方法,就像调用本地函数一样。RPC 屏蔽了底层网络通信的复杂性,使开发者能够通过简单的函数调用机制在分布式系统中执行操作。RPC 可以同步或异步地工作,广泛应用于分布式系统的服务间通信。
gRPC 是什么
gRPC 是一个现代化开源的高性能 rpc 框架,基于 HTTP/2 协议构建,支持多语言互操作。是 google 内部 rpc 系统 Stubby 的开源版本。gRPC 提供以下核心功能:
- 多语言支持:支持多种编程语言(如 Go、C++、Java、Python 等)。
- HTTP/2 传输:支持多路复用、流式通信、头部压缩和双向通信等特性。
- Protocol Buffers:gRPC 通常使用 Protocol Buffers(Protobuf)作为接口定义语言(IDL)来定义服务和消息格式,具有高效的序列化与反序列化性能。
- 流式数据传输:支持客户端流、服务端流和双向流。
- 负载均衡与认证:支持内置的负载均衡、认证和加密传输等功能。
gRPC-Go 是什么
gRPC-Go 是 gRPC 框架的 Go 语言实现。它为 Go 开发者提供了使用 gRPC 协议的能力,使得开发者能够通过 Go 语言构建高效、可靠的分布式系统和微服务。事实上,grpc 核心只依靠了标准库里的 http2 包用于建立 http2 链路和 net 包用于建立 tcp 链路,有了这些标准库的支持,我们完全可以自己手搓一个 rpc 框架。那么 grpc-go 的优点有哪些呢?
插件化的实现
- resolver:用于服务发现
- balancer:用于负载均衡
- IDL:用于代码生成
- compressor:用于数据压缩
- codec:用于数据编码
丰富的原生功能
- bi-directional streaming
- flow control
- binary logging
- channelz
- health checking
- rpc retry
- tracing
- service config
代码栈
普通用户只需要和代码生成的 API 和 grpc-go API 交互,不需要和底层框架和底层网络 http2 交互。
gRPC 核心实现
通信流程
下面是一个 unary rpc 的客户端和服务端的通信流程。
RPC 类型
生命周期
setup:一个客户端,一个后端服务由三台服务器组成(做负载均衡)
创建一个用于通信的 channel
创建流程:
- resolver 负责后端服务地址解析,客户端的服务发现流程
- balancer 负责选择目标地址,客户端的负载均衡流程
- 最终成功建立连接
balancer 工作流程
rpc 调用(客户端侧)
rpc 调用(服务端侧)
数据流
总结
gRPC 建立连接阶段
- tcp
- 初始化,用户传入可选的参数,如解析器,平衡器,拦截器等等
- 解析器解析后端服务地址,获取后端对应的 gRPC 服务器地址列表
- 平衡器则根据该列表建立 tcp 连接
- http2
- 帧交互,同步通讯能力
gRPC 调用阶段
- 客户端通过头帧将请求的服务名和方法名传输给服务器
- 客户端通过数据帧发送请求参数值
- 服务器使用客户端的提供的参数执行调用
- 服务器将执行结果封装成数据帧发回给客户端
- 客户端收到返回消息,实现了远程服务方法的本地调用。
延伸阅读
- Deep Dive: gRPC - Yuxuan Li, Google
- https://grpc.io/blog/a-short-introduction-to-channelz/
- https://github.com/grpc/proposal/
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。