gRPC 源码分析 (一) : 概述

4,274 阅读3分钟

gRPC 源码分析 (一) : 概述

gRPC 源码分析这个系列的文章记录了我在阅读学习 gRPC 源代码过程中的想法和发现, 阅读 gRPC 源代码,一方面是因为在工作中经常会用到 gRPC, 所以希望能够深入了解它底层的实现原理来更高效地去使用它, 另一方面, 也可以从源代码中一窥 gRPC 的设计者在构建这样一个高性能的 RPC 框架时的一些想法, 想想假如是我们来设计 gRPC, 它应该是什么样子的.

文章系列会借助于分析源码, 大体介绍 gRPC 连接中, client 和 server 之间是如何建立连接, 以及一个 gRPC call 完整的流程. 之后会逐个讨论 gRPC 中比较关键的功能是如何实现的, 并探究 gRPC 高性能的秘密.

系列文章中所列的源代码均来自 github.com/grpc/grpc-g…. 其中部分源代码过长, 因此只截取了和讨论主题相关的部分代码.

作为 gRPC 源码分析的第一章, 我们一起来大概了解一下 gRPC server 和 client 是如何建立连接并发送消息的.

gRPC 流程概括

Image.png

在 gRPC 中, 可以将 gRPC 的流程大致分为两个阶段, 分别是 RPC 连接阶段, 以及 RPC 交互阶段.

  • 在 RPC 连接阶段, client 和 server 之间建立起来 TCP 连接, 并且由于 gRPC 底层依赖于 HTTP2, 因此 client 和 server 还需要协调 frame 的相关设置, 例如 frame 的大小, 滑动窗口的大小等等.
  • 在 RPC 交互阶段, client 将数据发送给 server, 并等待 server 执行指定 method 之后返回结果.

Client 的流程

在 RPC 连接阶段, client 接收到一个目标地址 (string) 和一系列的 DialOptions, 然后

  1. 配置连接参数, interceptor 等, 启动 resolver.
  2. Resolver 根据目标地址获取 server 的地址列表 (比如一个 DNS name 可能会指向多个 server ip, dnsResovler 是 gRPC 内置的 resolver 之一). 启动 balancer.
  3. Balancer 根据平衡策略, 从诸多 server 地址中选择一个或多个建立 TCP 连接.
  4. client 在 TCP 连接建立完成之后, 等待 server 发来的 HTTP2 Settings frame, 并调整自身的 HTTP2 相关配置. 随后向 server 发送 HTTP2 Settings frame.

在 RPC 交互阶段,某个 local method 被调用之后,

  1. Client 创建一个 stream 对象用来管理整个交互流程.
  2. Client 将 service name, method name 等信息放到 header frame 中并发送给 server.
  3. Client 将 method 的参数信息放到 data frame 中并发送给 server.
  4. Client 等待 server 传回的 header frame 和 data frame. 一次 RPC call 的 result status 会被包含在 header frame 中, 而 method 的返回值被包含在 data frame 中.

Server 流程

在 RPC 连接阶段, server 在完成一些初始化的配置之后, 开始监听某个 TCP 端口. 在和某个 client 建立了 TCP 连接之后完成 HTTP2 settings frame 的交互.

在 RPC 交互阶段,

  1. Server 等待 client 发来的 header frame, 从而创建出一个 stream 对象来管理整个交互流程. 根据 header frame 中的信息, server 知道 client 请求的是哪个 service 的哪个 method.
  2. Server 接收到 client 发来的 data frame, 并执行 method.
  3. Server 将执行是否成功等信息方法放在 header frame 中发送给 client.
  4. Server 将 method 执行的结果 (返回值) 放在 data frame 中发送给 client.

总结

本章中我们大概了解了 server 和 client 在连接 RPC 流程中都经历了哪些步骤, 下一片文章将讨论 server 在 RPC 连接阶段所做的事情.