gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用要求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。
gRPC 是什么?
在 gRPC 里客户端运用可以像调用本地工具一样直接调用另一台不同的机器上做事端运用的方法,使得您能够更随意马虎地创建分布式运用和做事。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个做事,指定其能够被远程调用的方法(包含参数和返回类型)。在做事端实现这个接口,并运行一个 gRPC 做事器来处理客户端调用。在客户端拥有一个存根能够像做事端一样的方法。
gRPC 客户端和做事端可以在多种环境中运行和交互 - 从 google 内部的做事器到你自己的条记本,并且可以用任何 gRPC 支持的措辞来编写。以是,你可以很随意马虎地用 Java 创建一个 gRPC 做事端,用 Go、Python、Ruby 来创建客户端。此外,Google 最新 API 将有 gRPC 版本的接口,使你很随意马虎地将 Google 的功能集成到你的运用里。
利用 protocol buffers
gRPC 默认利用 protocol buffers,这是 Google 开源的一套成熟的构造数据序列化机制(当然也可以利用其他数据格式如 JSON)。正如你将不才方例子里所看到的,你用 proto files 创建 gRPC 做事,用 protocol buffers 类型来定义方法参数和返回类型。你可以在 Protocol Buffers 文档找到更多关于 Protocol Buffers 的资料。
Protocol buffers 版本
只管 protocol buffers 对付开源用户来说已经存在了一段韶光,例子内利用的却一种名叫 proto3 的新风格的 protocol buffers,它拥有轻量简化的语法、一些有用的新功能,并且支持更多新措辞。当前针对 Java 和 C++ 发布了 beta 版本,针对 JavaNano(即 Android Java)发布 alpha 版本,在protocol buffers Github 源码库里有 Ruby 支持, 在golang/protobuf Github 源码库里还有针对 Go 措辞的天生器, 对更多措辞的支持正在开拓中。 你可以在 proto3 措辞指南里找到更多内容, 在与当前默认版本的发布解释比较,看到两者的紧张不同点。更多关于 proto3 的文档很快就会涌现。虽然你可以利用 proto2 (当前默认的 protocol buffers 版本), 我们常日建议你在 gRPC 里利用 proto3,由于这样你可以利用 gRPC 支持全部范围的的措辞,并且能避免 proto2 客户端与 proto3 做事端交互时涌现的兼容性问题,反之亦然。
你好 gRPC!现在你已经对 gRPC 有所理解,理解其事情机制最大略的方法是看一个大略的例子。 Hello World 将带领你创建一个大略的客户端——做事端运用,向你展示:
通过一个 protocol buffers 模式,定义一个大略的带有 Hello World 方法的 RPC 做事。用你最喜好的措辞(如果可用的话)来创建一个实现了这个接口的做事端。用你最喜好的(或者其他你乐意的)措辞来访问你的做事端。定义做事创建我们例子的第一步是定义一个做事:一个 RPC 做事通过参数和返回类型来指定可以远程调用的方法。就像你在 概览 里所看到的, gRPC 通过 protocol buffers 来实现。
我们利用 protocol buffers 接口定义措辞来定义做事方法,用 protocol buffer 来定义参数和返回类型。客户端和做事端均利用做事定义天生的接口代码。
这里有我们做事定义的例子,在 helloworld.proto 里用 protocol buffers IDL 定义的。Greeter 做事有一个方法 SayHello ,可以让做事端从远程客户端吸收一个包含用户名的 HelloRequest 后,在一个 HelloReply 里发送回一个 Greeter。这是你可以在 gRPC 里指定的最大略的 RPC - 你可以在教程里找到针对你选择的措辞更多类型的例子。
syntax = \"大众proto3\"大众;option java_package = \"大众io.grpc.examples\"大众;package helloworld;// 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 greetingsmessage HelloReply { string message = 1;}
天生 gRPC 代码
一旦定义好做事,我们可以利用 protocol buffer 编译器 protoc 来天生创建运用所需的特定客户端和做事真个代码 - 你可以天生任意 gRPC 支持的措辞的代码,当然 PHP 和 Objective-C 仅支持创建客户端代码。天生的代码同时包括客户真个存根和做事端要实现的抽象接口,均包含 Greeter 所定义的方法。
(如果你没有在系统里安装 gRPC 插件和 protoc ,并且仅仅是要看一下这个例子,你可以跳过这一步,直接到下一步来查看天生的代码。)
Java
这个例子的构建系统也是 Java gRPC 本身构建的一部分 —— 为了大略起见,我们推举利用我们事师长西席成的例子代码。你可以参考 README 来看一下如何从你自己的 .proto 文件天生代码。
这个例子事师长西席成的代码在 src/generated/main下。
以下类包含所有我们须要创建这个例子所有的代码:
HelloRequest.java, HelloResponse.java和其他文件包含所有 protocol buffer 用来添补、序列化和提取 HelloRequest 和 HelloReply 类型的代码。GreeterGrpc.java, 包含 (还有其他有用的代码): Greeter 做事端须要实现的接口public static interface Greeter { public void sayHello(Helloworld.HelloRequest request, StreamObserver<Helloworld.HelloReply> responseObserver); }
客户端用来与 Greeter 做事端进行对话的 存根 类。就像你所看到的,异步存根也实现了 Greeter 接口。
public static class GreeterStub extends AbstractStub<GreeterStub> implements Greeter { ... }写一个做事器
现在让我们写点代码!
首先我们将创建一个做事运用来实现做事(你会记起来,我们可以是利用除了Objective-C and PHP 外的其他所有措辞来实现)。在本节,我们不打算对如何创建一个做事端进行更深入地磋商 —— 更详细的信息可以在你选择措辞对应的教程里找到。
做事实现
JavaGreeterImpl.java 准确地实现了 Greeter 做事所须要的行为。
正如你所见,GreeterImpl 类通过实现 sayHello 方法,实现了从 IDL 天生的GreeterGrpc.Greeter 接口 。
@Overridepublic void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {HelloReply reply = HelloReply.newBuilder().setMessage(\"大众Hello \公众 + req.getName()).build();responseObserver.onNext(reply);responseObserver.onCompleted();}
sayHello 有两个参数:
HelloRequest,要求。StreamObserver<HelloReply>: 应答不雅观察者,一个分外的接口,做事器用应答来调用它。为了返回给客户端应答并且完成调用:用我们的激动民气的构建并添补一个在我们接口定义的 HelloReply 应答工具。将 HelloReply 返回给客户端,然后表明我们已经完成了对 RPC 的处理。做事端实现
须要供应一个 gRPC 做事的另一个紧张功能是让这个做事实在在网络上可用。
JavaHelloWorldServer.java 供应了以下代码作为 Java 的例子。
/ The port on which the server should run /private int port = 50051;private Server server;private void start() throws Exception {server = ServerBuilder.forPort(port) .addService(GreeterGrpc.bindService(new GreeterImpl())) .build() .start();logger.info(\"大众Server started, listening on \"大众 + port);Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { // Use stderr here since the logger may has been reset by its JVM shutdown hook. System.err.println(\"大众 shutting down gRPC server since JVM is shutting down\公众); HelloWorldServer.this.stop(); System.err.println(\"大众 server shut down\"大众); }});}
在这里我们创建了合理的 gRPC 做事器,将我们实现的 Greeter 做事绑定到一个端口。然后我们启动做事器:做事器现在已准备好从 Greeter 做事客户端吸收要求。我们将在详细措辞对应的文档里更深入地理解这所有的事情是若何进行的。
写一个客户端客户真个 gRPC 非常大略。在这一步,我们将用天生的代码写一个大略的客户程序来访问我们在上一节里创建的 Greeter 做事器。
同样,我们也不打算对如何实现一个客户端程序深入更多,我们把这些内容放到教程里。
连接做事
首先我们看一下我们如何连接 Greeter 做事器。我们须要创建一个 gRPC 频道,指定我们要连接的主机名和做事器端口。然后我们用这个频道创建存根实例。
Javaprivate final ManagedChannel channel;private final GreeterGrpc.GreeterBlockingStub blockingStub;public HelloWorldClient(String host, int port) {channel = ManagedChannelBuilder.forAddress(host, port) .usePlaintext(true) .build();blockingStub = GreeterGrpc.newBlockingStub(channel);}
在这个例子里,我们创建了一个壅塞的存根。这意味着 RPC 调用要等待做事器应答,将会返回一个应答或抛出一个非常。 gRPC Java 还可以有其他种类的存根,可以向做事器发出非壅塞的调用,这种情形下应答是异步返回的。
调用 RPC
现在我们可以联系做事并得到一个 greeting :
我们创建并添补一个 HelloRequest 发送给做事。我们用要求调用存根的 SayHello(),如果 RPC 成功,会得到一个添补的 HelloReply ,从个中我们可以得到 greeting。JavaHelloRequest req = HelloRequest.newBuilder().setName(name).build();HelloReply reply = blockingStub.sayHello(req);
试一下!
你可以考试测验用同一个措辞在客户端和做事端构建并运行例子。或者你可以考试测验 gRPC 最有用的一个功能 - 不同的措辞间的互操作性,即在不同的措辞运行客户端和做事端。每个做事端和客户端利用从同一过 proto 文件天生的接口代码,则意味着任何 Greeter 客户端可以与任何 Greeter 做事端对话。