grpc 简介
gRPC是google推出的一款基于HTTP/2协议封装,使用protobuf3编解码消息体的开源rpc框架。
rpc就是远程过程调用 (Remote Procedure Call)。简单地说,就是在本地调用远程服务器上的服务,
gRPC基于以下理念: 定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个***存根***能够调用服务端的方法。
rpc框架通常要解决以下几个问题,gRPC也不例外:
- 服务描述语言
用于定义服务和以及数据内容的结构,这种语言一般与具体语言无关。
gRPC使用protobuf作为IDL,文件后缀为.proto。目前protobuf的最新版本是proto3。和proto2相比,它的特点是: 轻量简化的语法、一些有用的新功能,并且支持更多新语言。
grpc使用proto3,使用proto3定义完服务后,还需要使用编译器protoc将其转换为对应语言的代码,protoc通过-I指定不同的插件来生成不同语言的代码。 生成的代码同时包括客户端的存根和服务端要实现的抽象接口,以及序列化,反序列化相关代码 。
- 服务端如何确定客户端要调用的函数(消息路由),解决客户端调用的函数在服务端正确分发的问题。
grpc的消息路由大致分为下面三个步骤:
- 解码:对 HTTP/2 Body 进行应用层解码,转换成服务端接口的请求参数,将 PB 码流转换成对象;
- 路由:根据 URL 中的方法名从内部服务注册中心查询到对应的服务实例
- 调用:调用服务端接口实现类的指定方法,实现 RPC 调用
- 如何进行序列化和反序列化;
解决客户端和服务端进行交互时调用的函数,参数,返回值如何高效地在网络上进行传输的问题。
gRPC默认使用gpb(google protobuf)对数据进行序列化和反序列化。1中提到的protobuf不仅定义了服务和消息相关信息,也定义了消息载荷的结构 - 如何进行网络传输(选择何种网络协议);
多数RPC框架选择TCP作为传输协议,也有部分选择HTTP。gRPC就使用HTTP2。不同的协议各有利弊。TCP更加高效,而HTTP在实际应用中更加的灵活。
当然,还包括一些安全机制等。
gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。
- 如何高效快速地编写客户端和服务端代码;
好的RPC框架应该使使用者只需要关注服务功能代码的编写。框架会提供一系列相关的API供使用 者方便高效地进行相关开发。
编程语言,I/O模型,线程模型这些都由框架提供并通过API供使用者自由选择。当然有些rpc框架,3,4也可以自由组合和选择(如thrift,当然gRPC也可以,不过稍麻烦一些)。
grpc常见的4中service方法
- 一个 简单 RPC , 客户端使用存根发送请求到服务器并等待响应返回,就像平常的函数调用一样。
// Obtains the feature at a given position.
rpc GetFeature(Point) returns (Feature) {}
- 一个 服务器端流式 RPC , 客户端发送请求到服务器,拿到一个流去读取返回的消息序列。 客户端读取返回的流,直到里面没有任何消息。从例子中可以看出,通过在 响应 类型前插入
stream
关键字,可以指定一个服务器端的流方法。
// Obtains the Features available within the given Rectangle. Results are
// streamed rather than returned at once (e.g. in a response message with a
// repeated field), as the rectangle may cover a large area and contain a
// huge number of features.
rpc ListFeatures(Rectangle) returns (stream Feature) {}
- 一个 客户端流式 RPC , 客户端写入一个消息序列并将其发送到服务器,同样也是使用流。一旦客户端完成写入消息,它等待服务器完成读取返回它的响应。通过在 请求 类型前指定
stream
关键字来指定一个客户端的流方法。
// Accepts a stream of Points on a route being traversed, returning a
// RouteSummary when traversal is completed.
rpc RecordRoute(stream Point) returns (RouteSummary) {}
- 一个 双向流式 RPC 是双方使用读写流去发送一个消息序列。两个流独立操作,因此客户端和服务器可以以任意喜欢的顺序读写:比如, 服务器可以在写入响应前等待接收所有的客户端消息,或者可以交替的读取和写入消息,或者其他读写的组合。 每个流中的消息顺序被预留。你可以通过在请求和响应前加
stream
关键字去制定方法的类型。
// Accepts a stream of RouteNotes sent while a route is being traversed,
// while receiving other RouteNotes (e.g. from other users).
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
grpc 的安装
grpc只推荐使用git从github官方仓库clone
安装依赖
- 配置工具:build-essential, autoconf, libtool
- 测试支持:libgflags-dev
- 编译工具:clang, libc+±dev
从官方仓库克隆并编译安装
git clone https://github.com/grpc/grpc.git 或者 git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
cd grpc
git submodule update --init
#会自动下载grpc编译依赖的第三方库sudo make && make install