gRPC 概念
服务定义
像许多RPC系统一样,gRPC基于定义服务的想法,指定可以远程调用的方法及其参数和返回类型。默认情况下,gRPC使用protocol buffers作为接口定义语言(IDL)来描述服务接口和有效负载消息的结构。如果需要,用户也可以使用其他替代方案。
service HelloService { rpc SayHello (HelloRequest) returns (HelloResponse); } message HelloRequest { string greeting = 1; } message HelloResponse { string reply = 1; }
gRPC允许您定义四种服务方法:
一元RPCs,其中客户端向服务器发送单个请求并返回单个响应,就像正常的函数调用一样。
rpc SayHello(HelloRequest) returns (HelloResponse){ }
服务器流式RPC,其中客户端向服务器发送请求,并获得一个流来读回一系列消息。客户端从返回的流中读取,直到不再有消息。gRPC保证在单独的RPC调用中进行消息排序
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){ }
客户端流式RPC,其中客户端写入一系列消息,并再次使用提供的流将其发送到服务器。一旦客户端写完消息,它会等待服务器读取消息并返回响应。gRPC再次保证了单个RPC调用中的消息排序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) { }
双向流RPCs,其中双方使用读写流发送一系列消息。这两个流独立运行,因此客户端和服务器可以按照他们喜欢的顺序读写:例如,服务器可以等待接收所有客户端消息,然后再写响应,或者可以交替读取消息,然后再写消息,或者读写的某种组合。每个流中的消息顺序都被保留下来。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){ }
我们将在后面的RPC生命周期部分更详细地了解不同类型的RPC。
使用API surface
从.proto文件中的服务定义开始。gRPC提供protocol buffer编译器插件生成客户端和服务器端代码。gRPC用户通常在客户端调用这些API,并在服务器端实现相应的API。
在服务器端,服务器实现服务声明的方法,并运行gRPC服务器来处理客户端请求。gRPC基础设施对传入的请求进行解码,执行服务方法,并对服务响应进行编码。
在客户端,客户端有一个名为stub的本地对象(对于某些语言,首选术语是client ),该对象实现与服务相同的方法。然后,客户端可以在本地对象上调用这些方法,将调用的参数封装在适当的protocol buffer消息类型中-gRPC会在向服务器发送请求并返回服务器的协议缓冲区响应后进行查看。
同步与异步
同步RPC调用指定接口,直到来自服务器的响应到达为止,这与RPC期望的过程调用的抽象最接近。另一方面,网络本质上是异步的,在许多情况下,能够启动RPC而不阻塞当前线程是很有必要的。
大多数语言中的gRPC编程面有同步和异步两种风格。你可以在相应语言的教程和参考文档中找到更多信息(谷歌官方建设中)。