声明
本篇文章是在学习gRPC框架的过程中翻译的官方文档,非作者原创,官方文档参考gRPC,学习gRPC过程中,有些概念,思想理解翻译不到位还请多多指教。
本文主要介绍gRPC和protocol buffers,gRPC使用protocol buffers作为接口定义语言(IDL)和底层数据交换的格式。如果读者初次接触gRPC或protocol bufers,请继续阅读本文了解更多基本概念,如果你想快速深入并实际使用gRPC,请参考快速入门指南。
概述
在gRPC中,客户端应用可以像调用本地对象的方法一样直接调用部署在其他机器上的服务端应用的方法。gRPC降低了构建分布式应用和服务的难度。和其他RPC系统一样,gRPC的核心也是服务定义,定义可以被远程调用方法的入参和返回值。在服务端,服务器应用实现方法并启动一个gRPC服务器来处理客户端调用。在客户端,客户端有一个叫做stub的组件(在很多语言中称为客户端),提供和服务端一致的方法。
gRPC客户端和服务端可以在多种不同的环境下运行并相互通信,也可以使用gRPC支持的语言实现。例如,使用Java实现服务端,使用Go、Python或Ruby实现客户端。此外,Google最新的API都有对应的gRPC接口,可以更加容易的在应用构建Google的功能。
使用Protocol Buffers
gRPC默认使用protocl buffers,protoc buffers 是谷歌成熟的开源的用于结构化数据序列化的机制。gRPC也可以使用其他数据格式,比如JSON。下面简单介绍如何使用protocol buffers,如果读者对protocol buffers非常熟悉可以跳过该章节。
第一步:使用 .proto文件(以.proto为后缀的二进制文本文件)定义待序列化数据的结构。Protocol buffer中的数据称为“message”,每个message都是一个包含一系列称为“fields”的键-值对的小型化逻辑记录,下面是一个简单的例子。
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}
第二步:使用 protocol buffer 的编译器protoc从proto定义生成选择语言的数据接入层类。编译器生成的类提供简单的对field访问方法,例如name()和set_name(),这点和Java Bean中的Set和Get方法类似,也提供序列化和反序列化整个数据结构的方法。例如,加入选择的语言是C++,编译上面的例子可以得到一个名为Person的类,在应用中可以直接使用这个类填充,序列化和检索Person protocol buffer消息。
正如您将在示例中更详细地看到的那样,您可以在普通的proto文件中定义gRPC服务,并将RPC方法参数和返回类型指定为protocol buffer :
// greeter 服务定义.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 客户端请求消息包含用户名.
message HelloRequest {
string name = 1;
}
// 服务端响应包含一条greeting消息
message HelloReply {
string message = 1;
}
gRPC使用带有特殊gRPC插件的protoc
来生成proto文件中的代码。 但是,使用gRPC插件,您可以生成gRPC客户端和服务器代码,以及用于填充,序列化和检索消息类型的常规protocol buffer 代码。你可以从Protocol Buffers文档中获取到更多有关protocol buffer的信息,并能够获取到如何获取安装和你选定语言相关的protoc
。
Protocol buffer 版本
虽然protocol buffer 被开源用户使用已经有一段时间,但我们的示例使用了一种新的protocol buffer,称为proto3,它具有略微简化的语法,一些有用的新功能,并支持更多语言。proto3目前已经支持Java,C++,Python,Objective-C,C#,Ruby和JavaScript,也实现了对Go语言的支持。通常,虽然您可以使用proto2(当前默认protocol buffer版本),但我们建议您将proto3与gRPC一起使用,因为它允许您使用全系列gRPC支持的语言,并避免使用proto2客户端与使用proto3服务端通信时的兼容性问题,反之亦然。