1. grpc介绍

1.1 什么是grpc

在了解什么是grpc前,需要先知道什么是rpc。所谓的rpc(Remote Procedure Call),即远程过程的调用协议,我们也经常称为进程间通信协议,它可以让调用远程的函数像调用本地函数一样简单方便。

微服务和云原生架构出现后,我们构建一个系统时,各个业务功能都被拆分成了不同的服务模块,我们称之为微服务。而不同微服务间需要进行访问或者相互调用,便需要我们在不同微服务间定义统一的通信协议,构建一套进程间(或服务间)的通信技术来连接这些微服务。

我们常用的HTTP协议本身也是一种rpc协议,另外常见的rpc协议还有facebook的thrift和google的grpc,下面章节也会对比下这两种常见的协议和grpc的差别。

grpc是google于2015年开源的rpc框架,它具备标准化、可通用和跨平台的特点。这些特点使得不同微服务间可以方便的进行调用外,还支持可拓展的负载均衡、链路跟踪、健康检查等特性。而底层的通信,grpc采用的是HTTP/2来进行,性能和效率上能够得到充分的发挥。grpc也加入了CNCF(云原生计算基金会),逐渐的也成为了主流的社区上rpc框架。

landing-2.png

grpc作为一门框架或者说协议,不同的编程语言(java、c++、python等)都可以基于这套协议标准进行实现,而grpc-go就是grpc在go语言下的实现,本文后面的所有例子也会采用它来做示例和讲解。

1.2 grpc与protocol buffers的关系

微服务间通信时,需要依赖统一的通信协议。这里我们暂且将主调方称为客户端,被调方称为服务端。

服务端需要先定义服务接口,这种服务接口的描述语言,我们便称之为接口定义语言(interface definition language,IDL),而protocol buffers便是grpc所使用的接口定义语言。

protocol buffers是一种语言中立、平台无关,用于实现结构化数据序列化的可扩展机制。根据该机制,服务接口将会定义一个文件扩展名为.proto的文件。如何使用protocol buffers不是本文的重点,具体可以参考官网。

这里提供一个grpc官网给出的一个proto文件示例:

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

我们通过proto文件定义好服务接口后,便需要根据这个定义生成服务端代码,我们称被生成的服务端代码为服务端骨架(skeleton)。

另一方面,还需要根据proto文件的服务接口定义生成客户端代码,这份代码我们称之为桩代码或者存根(stub)。有了桩代码后,客户端便可以像调用本地函数一样调用远程服务端的函数了。

grpc.jpg

Protocol buffers官方支持常用语言的代码生成,如go、c++、java、python等,可以查看这个文档。如果官方没有提供,github上也有一些第三方开源库提供支持。

1.3 与其他rpc技术的对比

1.3.1 HTTP