一架梯子,一头程序猿,仰望星空!

grpc 框架教程


gRPC 是一个高性能、跨平台、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C/C++、Java、Python、Ruby、C#、PHP、Node.js、Go 语言等版本,几乎你想到的语言都支持了.

gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

下面先介绍grpc相关概念

1.grpc是什么?

在 gRPC 里客户端应用可以像调用本地方法一样直接调用另一台机器上服务端应用的方法,这样我们就很容易创建分布式应用和服务。跟其他 RPC 系统类似,gRPC 也是基于以下理念:首先定义一个服务,定义能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个方法,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根,这个存根就是长得像服务端一样的方法(但是没有具体实现),客户端通过这个存根调用服务端的方法。

grpc工作原理,如下图:

2.grpc使用的协议

gRPC 默认使用 protocol buffers,这是 Google 开源的一套成熟的结构数据的序列化机制,当然也可以使用其他数据格式如 JSON,不过通常都使用protocol buffers这种灵活、高效的数据格式,如果不了解protobuf语法,点击这里学习protocol buffers入门教程

3.服务定义

使用gprc,首先需要定义服务, 指定其可以被远程调用的方法及其参数和返回类型。

服务,你可以理解成服务端api接口的集合,对外提供一些功能。

通过protobuf定义服务的例子:

// 定义一个叫HelloService的服务
service HelloService {
  // 定义一个叫SayHello的方法,这个方法接受HelloRequest消息作为参数,返回HelloResponse消息
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

// 定义HelloRequest消息
message HelloRequest {
  required string greeting = 1;
}

// 定义HelloResponse消息
message HelloResponse {
  required string reply = 1;
}

如果你把service和message关键词当成class,是不是跟类定义很像!

提示:本节主要介绍grpc的一些关键概念,具体不同的开发语言如何使用,后面的教程会讲解。

gRPC 允许你定义四类服务方法,下面分别介绍如何定义,以及客户端和服务端的交互方式。

3.1. 单向RPC

即客户端发送一个请求给服务端,从服务端获取一个应答,就像一次普通的函数调用。

rpc SayHello(HelloRequest) returns (HelloResponse){
}

3.2. 服务端流式 RPC

即客户端发送一个请求给服务端,可获取一个数据流用来读取一系列消息。客户端从返回的数据流里一直读取直到没有更多消息为止。

通俗的讲就是客户端请求一次,服务端就可以源源不断的给客户端发送消息。

// 注意stream关键词在什么地方
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
}

3.3. 客户端流式 RPC

即客户端用提供的一个数据流写入并发送一系列消息给服务端。一旦客户端完成消息写入,就等待服务端读取这些消息并返回应答。

通俗的讲就是请求一次,客户端就可以源源不断的往服务端发送消息。

// 注意stream关键词在什么地方
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
}

3.4. 双向流式 RPC

即两边都可以分别通过一个读写数据流来发送一系列消息。这两个数据流操作是相互独立的,所以客户端和服务端能按其希望的任意顺序读写,例如:服务端可以在写应答前等待所有的客户端消息,或者它可以先读一个消息再写一个消息,或者是读写相结合的其他方式。每个数据流里消息的顺序会被保持。

类似tcp通信,客户端和服务端可以互相发消息。

// 注意stream关键词在什么地方
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
}

提示:本序列教程主要翻译gRPC官方文档。