Review - gRPC Design and Implementation

本周文章是一个2016年的slide,gRPC Design and Implementation

gRPC介绍

gRPC源自Google内部RPC项目Stubby。Stubby这个项目支撑了谷歌内部所有的应用和系统,Google云中全平台百亿次每秒的请求量,提供了C++,Java,Python和Go的API,但是因为和内部工具紧密结合所以并不适合开源。这个项目为后面的开源积累了伸缩性、性能和API经验。

gPRC的特点主要有:

  • 跨语言跨平台框架
    • gRPC提供了C、Java和Go版本的原生实现
    • C++, C#, Node, ObjC, Python, Ruby, PHP通过封装C语言gRPC实现
    • 支持 Linux, Android, iOS, MacOS, Windows 多个平台
  • 通过HTTP/2 + TLS通信
    • 撬动目前使用的网络协议和基础组件
    • 通过多线程框架流式发送公用一个连接,高效使用TCP
    • 原生支持加密双向流式通信

跨平台

其中C/C++的实现主要目标是高通量、低延迟与可伸缩性,同时减小外部依赖。

为何要用HTTP/2作为传输协议

为何用HTTP

  • 网络基础设施对HTTP充分支持
  • 基本观点是把RPC当成是HTTP对象
    • URI –> 请求方法(request method)
    • content —> 请求参数(request parameters)
    • HTTP response —> 请求返回

HTTP/1.1的问题

  • Request-Response协议:串行而不能并行,为防止多个请求间的顺序停顿需要多个链接
  • content可压缩但Header不行
  • 单向Streaming但不能双向

HTTP2好处

  • client-server间维持一个连接
  • 通过framing实现流多路复用
  • 压缩二进制framing层
  • Content压缩
  • 原生支持双向流式传输
  • http2demo提供了一个示例

gRPC

介绍了Protocol Buffer作为数据压缩方式,使用gRPC ServergRPC stub的传输方式。然后给了一个例子做示范。

C++应用与性能

跨语言性能和层级架构一图流介绍:

C核心代码设计原则

  • 包括带有身份验证的完整HTTP/2传输实现(不使用外部依赖的哲学)
  • 管理与系统的交互
    • 接收异步事件通知(套接字事件,定时器)
    • 可以使用通用轮询或epoll和IOCP等特定于平台的机制
  • 提供供上层语言调用的接口
    • 完成队列作为系统级事件通知的抽象(绑定到RPC语义,而不仅仅是套接字上的字节)
  • 不打算作为应用程序级API,所以不支持protobufs
  • Core使用应用程序线程来完成其工作*
    • 在读取现场中读取消息,并在这个线程完成外部库中要做的工作

基础C++ API和线程模型

  • 同步通信
    • 客户端:阻塞等待response(unary)或read(streaming)
    • 服务器端:把每个进来的RPC请求塞入一个动态大小的线程池中去处理,这是gRPC C/C++唯一使用自身线程支持RPC处理的一个API
  • 异步通信
    • 客户端和服务器端都可以通过CompletionQueue去等待一个Event
  • 可以混用客户端/服务器,甚至可以在一个服务器使用多个Method

性能测试

比较老的数据了,就不做详细解读