gRPC实战包含一系列文章,包括原创和翻译。最终会形成一个完整的系列,后续会不断完善,增加新的内容:
- gRPC简介:why,what,how?
- gRPC服务健康检查最佳实践
- Kubernetes中使用envoy负载均衡gRPC流量
- 用Golang编写通过gRPC进行通信的服务
- 如何在NodeJS中有效使用gRPC流
=============================================================
Why gRPC?
让我们从一个简单的问题开始:gRPC的动机是什么?或是gRPC试图解决的问题是什么?
好吧,答案是通信。
应用程序是使用不同的编程语言编写的。
例如,后端可以用Go编写,而前端(例如android app用Java编写,iOS app用Swift编写)。
那么他们如何互相通信
当今的趋势是使用微服务架构。因此,即使在后端,根据业务需求和技术约束,我们可能还会有许多用不同语言(例如Go,Python或Rust)编写的服务。
使用gRPC的动机:不同语言之间通信
- 前后端采用了不同的语言
- 微服务架构,采用了不同的语言
-
通过遵守一致的约定去交互信息
- 通信通道:REST,SOAP,消息队列
- 身份验证机制:Basic,OAuth,JWT
- 负载类型:JSON,XML,binary
- 数据模型
- 错误处理
因此,为了彼此通信,他们必须都遵守一组API约定。例如:通信通道,身份验证机制,有效载荷格式,数据模型以及如何处理错误。
有太多事情需要考虑,这就是为什么构建API真的很困难。
使用gRPC的动机:简单而高效的通信
更重要的是,我们希望通信高效,快速且轻巧。您知道,微服务之间的交换消息数量巨大。因此,通信越快越好。
另外,在某些环境(例如移动应用)中,网络速度和带宽受到限制,拥有轻量级的通信协议与服务器进行交互非常重要。
最后但并非最不重要的一点是,我们希望沟通很简单。假设我们正在构建一个包含数百个甚至数千个微服务的系统。我们绝对不希望将大部分时间花在编写代码上只是为了让他们彼此通信,对吗?
我们想要的是某种框架,允许开发人员专注于实现其服务的核心逻辑。并将其他所有内容留给框架处理。
该框架就是gRPC。
What is gRPC? How it works?
gRPC是最初由Google开发的高性能,开源,功能丰富的RPC框架,现在与Kubernetes或Prometheus一样,它是云原生计算基础(或CNCF)的一部分。
RPC是什么? RPC代表远程过程调用。它是允许程序执行位于其他计算机上的另一个程序的过程的协议。
令人敬畏的是,开发人员不必明确编码网络交互的细节。它由基础框架自动处理。
因此,在客户端代码中,看起来我们只是在直接调用服务器代码的功能。即使客户端和服务器上的代码是用不同的编程语言编写的,它也可以工作。像本示例一样,客户端代码用Go编写,服务器代码用Rust编写。
那么gRPC如何做到这一点?基本上,客户端具有一个存根,该存根提供与服务器相同的方法(或功能)。该存根由gRPC自动为您生成。
存根将在后台调用gRPC框架,以通过网络与服务器交换信息。
瞧,神奇的是一切正常。由于存根,客户端和服务器现在只需要关心实现其核心服务逻辑。
接下来,我们将看到如何在protocol buffer的帮助下生成gRPC存根。
gRPC如何生成代码?
代码生成是gRPC的最重要功能之一。
为了为服务器和客户端生成存根,我们首先需要编写API协定,该协定包括在protocol buffer文件中的服务及其有效载荷消息的描述,如下所示:
syntax = "proto3"
message HelloRequest {
string name = 1;
}
message HelloResponse {
string greet = 1;
}
service HelloService {
rpc Hello(HelloRequest) return (HelloResponse);
}
在此文件中,定义了一个Hello方法,该方法将HelloRequest作为输入并返回HelloResponse。 HelloRequest仅包含一个字符串名称,而HelloResponse具有一个字符串。
protocol buffer编译器从此proto文件生成服务器和客户端存根代码。根据编程语言,我们将不得不告诉编译器为其使用正确的gRPC插件。
为Rust和Go生成的代码将如下所示:
OK,所以您可能想知道为什么gRPC使用protocol buffer?好吧,有很多原因。
首先,它非常易于阅读和理解。
其次,它的语言可与多种语言自动生成代码互操作
第三,它表示二进制格式的数据,与某些基于文本的格式(如JSON或XML)相比,它的大小更小,传输速度更快,序列化的效率更高。
它在客户端和服务器之间提供了一种强类型的API契约,使用它非常安全, 而且确保向后和向前的兼容性。
听起来很棒,对吗?但是,使用gRPC一定需要protocol buffer吗?
答案是不。您可以改用Google Flatbuffers或Microsoft Bond。但是我认为protocol buffer已经是一个不错的选择。
它支持许多流行的编程语言,其中10种已正式支持,其中纯实现了Go,Java,NodeJS,另外7种是gRPC核心C的包装,即C ++,C#,Objective-C,Python,Ruby,Dart和PHP。
此外,还有许多其他语言的非官方库,例如Swift,Rust,TypeScript,Haskell等。
gRPC与HTTP2
gRPC使用HTTP/2作为其传输协议,因此它继承了HTTP/2提供的一些出色功能,例如二进制帧,与其他基于文本的协议相比,它具有高性能,强健性,更轻便的传输和更安全的解码能力。而且因为它是二进制文件,所以它与protocol buffer完美结合。
HTTP/2还使用HPACK压缩报头,这将减少开销成本并提高性能。
在HTTP/2中可以进行多路复用,这意味着客户端和服务器可以通过单个TCP连接并行发送多个请求和响应。这将有助于减少延迟并提高网络利用率。
最后,HTTP/2允许服务器推送,其中来自客户端的1个单个请求使服务器可以发回多个响应。在许多情况下,当服务器确切知道客户端需要什么资源并在请求之前将其发送时,这对于减少客户端和服务器之间的往返延迟非常有价值。