grpc入门(一)
一.什么是grpc
grpc是谷歌开源的一款高性能的rpc框架 (https://grpc.io),可以使用protocol buffers作为IDL(Interface Definition Language)文件,也可以作为底层的信息传输的格式(这也是本博文所介绍的方式)。
以下内容属于笔者对 what is grpc? 的翻译,原文请见: https://grpc.io/docs/guides/index.html。
grpc的客户端应用可以像访问本地方法一样调用其他机器上的服务端应用的方法,使得我们可以非常简单的创建分布式应用与服务。和其他很多rpc框架一样,gprc也是创建一个服务接口,然后指定调用远程方法所需的参数和返回类型。在服务端,需要实现服务的接口,然后启动一个服务器来处理客户端的调用;在客户端,需要桩代码,提供与服务端相同的方法。
grpc的客户端与服务端可以在不同的环境下相互调用,例如: 从谷歌内部的服务到我们的桌面应用,这些应用可以使用gprc所支持的不同的语言来实现。因此,你可以使用grpc轻松的创建一个java的服务端应用,使用go或者python或者ruby语言创建一个客户端应用。另外一方面,谷歌最近的所公布的一些接口使用了grpc,如此一来,你可以将谷歌的一些功能集成到你的应用中。
grpc默认采用了protocol buffers, 这是google已经开源了的并且非常成熟的用于数据结构序列化的框架(也可以使用其他的数据格式例如json)。在这里快速的介绍他的用法,如果你对protocol buffers已经非常熟悉额了,你可以跳过这篇文章直接进入到下一个章节。
首先,当使用protocol buffers来序列化数据,需要编写一个proto文件,文件中定义你想要序列化的结构数据,注意文件名必须以 .proto结尾。protocol buffers的数据是一个结构化的消息,每个消息都是一小的逻辑信息的记录,消息中包含了一系列的键值对,称之为属性,下面有一个简单的例子:
message Person { string name = 1; int32 age = 2; bool has_ponycopter = 3; }
接着,当你已经制定了你的数据结构,你就可以使用protocol buffers编译命令protoc来生成你所擅长的语言对应的类。类中提供了简单的方法来操作每个属性(例如name()和set_name()), 另外这些方法内部可以将数据序列化为元数据传输给对方,也可以将对方发送过来的元数据进行解析。拿一个具体的例子来说,如果你使用的是c++,编译如上的例子后会生成一个叫做Person的类,你可以使用这个类来构建,序列化,并且得到 Person对应的protocol buffers消息。
下面会给出一个更加详细的例子,你可以在一个普通的proto文件中定义grpc的服务,rpc的方法的参数和返回类型需要声明为一个protocol buffers的消息。
// The greeter 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; }
grpc可以使用带插件的protoc命令将你编写的proto文件生成代码。然而,使用grpc的插件的时候,你可以生成grpc的客户端和服务端代码,和一般的protocol buffers代码一样,可以构建,序列化,获取消息。
你可以从 Protocol Buffers document 文档中获取更多关于protocol buffers的说明,也可以从中学到如何获得和安装你所擅长的编程语言的 protoc 插件。
二. grpc的四种定义方式
grpc允许用户定义四种形式的rpc方法(原文参照:https://grpc.io/docs/guides/concepts.html):
A.客户端发送请求到服务端,然后服务端给出一个响应,就像一个普通的方法定义一样,如下所示:
rpc SayHello(HelloRequest) returns (HelloResponse) {}
B.服务端的流式rpc:客户端发送一个请求到服务端,然后得到一个流用于读取服务端的的消息,客户端从返回的流中读取所有的信息,如下所示:
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse) {}
C.客户端流式rpc: 客户端使用流将信息发送个服务端,只要客户端发送完所有的信息给服务器,就开始等待服务端的响应,如下所示:
rpc LotsOfGreeting(stream HelloRequest) returns HttpResponse {}
D.双向流式rpc:服务端与客户端都是用读写流发送数据给对方。这两个流式相互独立的,所以他们的读写可以是任意顺序的,例如:服务端在接受到客户的所有的信息之前就已经开始响应,也可以先读取数据然后再写数据,或者其他任何组合,如下所示:
rpc BidiHello(stream HelloRequest) returns HelloResponse {}