作为同样出自google的技术,go和grpc 它们有着相似特征。 比如都使用 y compiler实现某些功能,大量功能依赖于此。
1 gRPC 简介
gRPC是大量微服务之间通信的基础设施。
通用 RPC 基础设施来连接在其数据中心内和跨数据中心运行的大量微服务。它使用 .proto
文件定义服务。
gRPC支持四种RPC方式:
一元、服务器流、客户端流和双向流。
gRPC强调元数据交换、流控制、优雅关闭和互操作性等设计原则。
2015 年 3 月,Google 决定构建下一个版本的 Stubby 并使其开源。结果就是 gRPC,它现在在 Google 以外的许多组织中用于支持从微服务到计算“最后一英里”(移动、Web 和物联网)的用例。
在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像它是本地对象一样,使您更容易创建分布式应用程序和服务。
与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定可以远程调用的方法及其参数和返回类型。在服务端,服务端实现这个接口并运行一个 gRPC 服务器来处理客户端调用。
在客户端,客户端有一个存根(在某些语言中仅称为客户端),它提供与服务器相同的方法
2 gRPC 设计原则
允许用户定义四种grpc方法
https://grpc.io/blog/principles/
从.proto
文件中的服务定义开始,gRPC 提供了生成客户端和服务器端代码的协议缓冲区编译器插件。gRPC 用户通常在客户端调用这些 API,并在服务器端实现相应的 API。
元数据是关于特定 RPC 调用的信息(例如身份验证详细信息),采用键值对列表的形式,其中键是字符串,值通常是字符串,但也可以是二进制数据。
元数据对 gRPC 本身是不透明的——它允许客户端提供与服务器调用相关的信息,反之亦然。
定义四种服务方法:
- 一元 RPC,其中客户端向服务器发送单个请求并获得单个响应,就像正常的函数调用一样。
- 服务器流式 RPC,其中客户端向服务器发送请求并获取流以读回一系列消息。客户端从返回的流中读取,直到没有更多消息为止。gRPC 保证单个 RPC 调用中的消息顺序。
- 客户端流式 RPC,其中客户端写入一系列消息并将它们发送到服务器,再次使用提供的流。
一旦客户端完成了消息的写入,它就会等待服务器读取它们并返回它的响应。gRPC 再次保证了单个 RPC 调用中的消息顺序
- 双向流式 RPC,双方使用读写流发送一系列消息。这两个流独立运行,因此客户端和服务器可以按照他们喜欢的任何顺序读取和写入:
例如,服务器可以在写入响应之前等待接收所有客户端消息,或者它可以交替读取消息然后写入消息,或其他一些读取和写入的组合。保留每个流中消息的顺序。
-
3 资源文档
- 1 原则与要求
2 服务不是对象,消息不是引用
提倡系统间粗粒度消息交换的微服务设计理念,同时避免如下问题:
- 4 覆盖范围和简单性
该堆栈应该在每个流行的开发平台上都可用,并且人们可以轻松地为他们选择的平台构建。它在 CPU 和内存有限的设备上应该是可行的。
- 5 免费开放
让所有人免费使用基本功能。将所有工件作为开源工作发布,并带有应促进而不是阻碍采用的许可。
- 6 互操作性和范围
有线协议必须能够在常见的互联网基础设施上进行遍历。
- 7 通用和高性能
与特定于用例的堆栈相比,该堆栈应适用于广泛的用例类别,同时几乎不会牺牲性能。
- 8 分层
堆栈的关键方面必须能够独立发展。对有线格式的修订不应破坏应用层绑定。
- 9 有效载荷不可知
不同的服务需要使用不同的消息类型和编码,例如protocol buffers、JSON、XML和Thrift;协议和实现必须允许这样做。
同样,有效载荷压缩的需求因用例和有效载荷类型而异:协议应允许可插入的压缩机制。
- 10 流媒体
存储系统依靠流和流控制来表达大型数据集。其他服务,如语音到文本或股票行情,依靠流来表示时间相关的消息序列。
- 11 阻塞和非阻塞
支持客户端和服务器交换的消息序列的异步和同步处理。这对于在某些平台上扩展和处理流至关重要。
12 取消和超时
操作可能是昂贵且长期存在的——取消允许服务器在客户端表现良好时回收资源。
当跟踪工作的因果链时,取消可能会级联。客户端可能会指示调用超时,这允许服务根据客户端的需要调整其行为。
- 13 优雅关闭
必须允许服务器通过拒绝新请求而优雅地关闭,同时继续处理正在进行的请求。
- 14 流量控制
客户端和服务器之间的计算能力和网络容量往往不平衡。
流控制允许更好的缓冲区管理以及通过过度活跃的对等方提供对 DOS 的保护。
- 15 可插拔
有线协议只是功能性 API 基础设施的一部分。大型分布式系统需要安全、健康检查、负载平衡和故障转移、监控、跟踪、日志记录等。
实现应提供扩展点以允许插入这些功能,并在有用的情况下提供默认实现。
- 16 作为 API 的扩展
需要服务之间协作的扩展应该尽可能使用 API 而不是协议扩展。
这种类型的扩展可能包括健康检查、服务自省、负载监控和负载平衡分配。
- 17 元数据交换
身份验证或跟踪等常见横切关注点依赖于不属于服务声明接口的数据交换。
部署依赖于它们以与服务公开的单个 API 不同的速度发展这些功能的能力。
- 18 标准化状态码
客户端通常以有限的方式响应 API 调用返回的错误。
应限制状态代码命名空间以使这些错误处理决策更清晰。
如果需要更丰富的特定于域的状态,则可以使用元数据交换机制来提供。
4 安装 依赖包
协议编辑器的go插件
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
更新 PATH 以便protoc编译器可以找到插件
export PATH = "\$PATH:\$(go env GOPATH)/bin"
1 示例代码
git clone -b v1.46.0 --depth 1 https://github.com/grpc/grpc-go
2 切换到快速启动示例目录
cd grpc-go/example/helloworld
3 协议gRPC编译器插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
执行后将在C:\Go\bin 新增两个编译后文件
protoc-gen-go.exe protoc-gen-go-grpc.exe