grpc通信模式
- 一元RPC
- 简单RPC,客户端调用远程方法时,客户端发送请求至服务器并获得一个响应,与响应一起发送的还有状态细节以及trailer元数据
- 一元RPC消息流
一个请求,一个响应
- 服务器端流RPC
- 服务然端在收到客户端的请求消息后,会发回一个响应的序列,这种多个响应所组成的序列也被称为 “流’在将所有的服务器端响应发送完毕之后,服务器揣会以 trailcr元数据的形式将其状态发送给客户端,从而标记流的结束.
- 信息流:
- 客户端流RPC、
- 客户端会发送多个请求给服务器端,而不再是单个请求 。 服务器端则会发送一个响应给客户端 。 但是,服务器端不一定要等到从客户端接收到所有消息后才发送响应。基于这样的逻辑 ,我们可以在接收到流中的一条消息或几条消息之后就发送响应,也可以在读取完流中的所有消息之后再发送响应.
- 消息流:
- 双向流RPC
- 客户揣以消息流的形式发送请求到服务器端,服务器端也以消息流的形式进行响应
- 消息流:
grpc底层原理
1. 网络实现RPC过程
关键的步骤。
1.客户端进程通过生成的存根调用 getProduct 方怯。
2. 客户端存根使用已编码的消息创始 HTTP POST请求。在 gRPC,所有的请求都是 HTTP POST 请求,并且 content-type 前缀为 application/grpc。要调用的远程方法(Productlnfo/getProduct) 是以单独的 HTTP 头信息的形式发送的。
3. HTTP 请求消息通过网络发送到服务器端。
4 当接收到消息后,服务器端检查消息头信息,从而确定需要调用的服务方怯,然后将消息传递给服务器端骨架。
5. 服务器端骨架将消息字节解析成特定语言的数据结构。
6. 借助解析后的消息,服务发起对getProduct方法的本地调用。
服务方法的响应经过编码后被发送回客户端。 响应消息会遵循我们在客户端上所观察到的 相同过程(响应→编码→线路上的 HTTP响应) ,该消息会被解包,它的值将返回给等待的客户揣进程。
2. protocol buffers编码(数据序列化协议)
编码后的字节流
标签组成:
- 字段索引:proto文件中定义消息时,为每个消息字段所设置的唯一数字
- 线路类型(wire type):基于字段类型,确定值的长度
编码技术:
- Varint (可变长度整数)是使用单字节或多字节来序列化整数的方法
- 有符号维数是能够表示正整数值和负整数值的类型
- 采用zigzag编码
- 非Varint类型:固定数量的字节, 字节数与实际值没有关系
- 字符串类型:基于长度分隔的线路类型
基于长度前缀的消息分帧
- 目的:为了打包要通过网络发送的消息
-
基于HTTP/2的grpc
流(stream):在一个已建立的连接上的双向字节流。一个流可以携带一个或多条消息
- 帧(frame):HTTP/2中最小的通信单元。每一帧都包含一个帧头,它至少要标记该帧所属的流
- 消息(message):完整的帧序列. 映射为为一条逻辑上的HTTP消息,由一 帧或多帧组成。这样的话,允许消息进行多路复用,客户端和服务器端能够将消息分解成独立的帧,交又发送它们,然后在另 一端进行重新组合.
grpc原始实现框架
总结:
gRPC构建在两个快速、高放的协议之上,也就是 protocol buffers 和 HTTP/2, protocol buffers 是 一 个语言中立、平台无关的数据序列化协议,并且提供了可扩展的机制来实现结 构化数据的序列化。当序列化完成之后,该协议会生成二进制载荷,这种载荷会比常见的 JSON载荷更小,并且是强类型的。 序列化之后的二进制裁荷会通过名为 HTTP/2的二进制传输协议进行发送.
HTTP/2 是互联网协议 HTTP的第 2 个主版本。HTTP/2是完全多路复用的,这意味着 HTTP/2 可以在 TCP 连接上并送发送多个数据请求。这样一来,使用HTTP/2编写的应用 程序变快、更简洁、更稳健。
超越基础知识:
- 拦截器
- 截止时间
- 取消
- 错误处理
- 多路复用
- 元数据
- 负载均衡
安全的grpc
- 使用TLS认证grpc通道
- 启用单向安全连接
- 启用mTLS保护的连接
- 对grpc调用进行认证
- 使用basic认证
- 使用Oauth2.0
- 使用jwt
- 使用基于令牌的谷歌认证
grpc生态系统
- grpc网关:让 protocol buffers 编译器读取 gRPC 服务定义,生成反向代理服务器端,该服务器端能够将RESTful JSON API翻译为grpc
- grpc的HTTP/json转码:转码 (transcode) 指的是将 HTTP JSON 调用转换成 RPC. 并将它们传递给 gRPC 服务的过程。当客户端应用程序不支持 gRPC. 并且需要通过基于 HTTP 的 JSON 方式提供对 gRPC服务的访问时. 转码非常有用
- grpc服务器端反射协议:服务器定义的 一个服务,它能提供该服务器端上可公开访问的 gRPC 服务的信息。简而占之,服务器端反射向客户端应用程序提供服务器端所注册的服务的定义信息.因此,客户端不需要预编译服务定义就能与服务进行通信了.
- grpc中间件:基于 Go 语言的 一 组拦戳 器、辅助器 (helper) 和工具的集合 , 在构建基于 gRPC 的应用程序时,我们会用到它们. 它允许在客户端或服务器端以拦截器链的形式应用多个拦截器。同时,因为拦截器经常用 来实现通用 的模式,如认证 、 日志 、 消息 、校验、重试或监控
- 健康检查协议:允许 gRPC 服务暴话服务器的状态,这样消费者就能探查服务器的健康信息。
- 健康检查探针:grpc_health_probe 是社区提供的 一 个工具,用来检查服务嚣的健康状态, 服务器通过 gRPC健康检查协议将它的状态暴露为服务.
生成环境运行grpc
- 测试grpc应用程序
- 测试grpc服务器端:testing包
- 测试grpc客户端:Mockgen 生成的包以及 gomock包
- 负载测试:ghz
- 持续集成
- 可观察性
- 度量指标:OpenCensus、Prometheus
- 日志:日志拦截器
- 跟踪:trace
- 调试和问题排查
- 启用额外日志
- 部署
- docker
- Kubernetes
- deployment资源(pod)
- Kubernetes Job:一个 pod运行指定的次数.
- Kubernetes Ingress 对外暴露 gRPC 服务(负载均衡器)