站在巨人的肩膀上:gRPC 通过 HTTP/2 构建云原生时代的通信标准
gRPC:云原生时代的通信标准
gRPC 将 HTTP/2 作为其传输层,并在此基础上定义了自身的通信语义。gRPC 支持四种服务方法类型,它们都映射到 HTTP/2 的流模型上。1)Unary RPC: 客户端发送单个请求,服务器返回单个响应(类似传统请求-响应)。2)Server Streaming RPC: 客户端发送单个请求,服务器返回一个消息序列(流)。3)Client Streaming RPC: 客户端发送一个消息序列(流),服务器返回单个响应。4)Bidirectional Streaming RPC: 客户端和服务器都可以独立地发送一个消息序列(流)。
请求 (Request) 结构
gRPC 的 Request 包含请求头(Request Headers),请求体(Request Body)和 EOS(end-of-stream)。请求头使用 HTTP/2 的 headers, 使用 HEADERS 和 CONTINUATION 帧派发。请求头有 Call-Definition 和 Custom-Metadata。其中 grpc-前缀为 gRPC 自己保留。
请求体使用 DATA 帧派发,请求体是长度前缀消息。它有一个 Compressed flag 用来表示 message 是否压缩,为 1 表示采用了压缩算法(具体的压缩算法在 HEADERS 帧中定义)。后面跟着四字节的 message length 以及实际的 message。

EOS 会在 DATA 帧里面带上了 END_STREAM 这个 flag。用来表示请求消息的结束。
响应 (Response) 结构
gRPC 的 Response 包含响应头(Response-Headers),响应体(Response Body)和 Trailers。
发完响应头,使用 DATA 帧派发响应体。响应体是长度前缀消息。
结束标志不与数据帧一起发送,而是作为单独的头部发送,称为 Trailers。 如果遇到了错误,也可以直接返回 Trailers-Only。Trailer 是一种特殊的元数据,通常包含有关执行的状态信息,例如状态码( grpc-status)和状态消息(grpc-message)gRPC 之所以要用单独的 Trailers 来标志响应结束。是因为在 streaming 模式下,所有消息没有传输完成之前,gRPC 也不知道要传什么样的 grpc-status 。
服务描述
gRPC 利用 .proto 文件中的 service 来定义 RPC 接口。
在上述 .proto 文件中,定义了一个名为 Greeter 的服务,它包含一个名为 SayHello 的方法。该方法接收 HelloRequest 消息并返回 HelloReply 消息。gRPC 工具链会基于此 IDL 生成各种语言的客户端存根(stub)和服务端骨架(skeleton)。开发者通过调用存根上的方法,就如同调用本地方法一样,gRPC 框架会处理底层的序列化、网络通信和方法分发。一个 gRPC 定义包含三个部分,包名、服务名和接口名,连接规则如下:
SayHello 的包名是 demo.hello,服务名是 Greeter,接口名是 SayHello,所以对应的路径就是 /demo.hello.Greeter/SayHello。
gRPC 基于这样的一个设计理念:定义一个服务,及其被远程调用的方法(方法名称、入参、出参)。开发者可以像调用本地方法一样,使用 gRPC 客户端存根(stub)调用远程机器上 gRPC 服务的方法。gRPC 的客户端和服务端都可以用任何支持 gRPC 的语言来实现,例如一个 gRPC 服务端可以是 C++语言编写的,以供 Ruby 语言的 gRPC 客户端和 JAVA 语言的 gRPC 客户端调用,如下图所示。

未完待续.
很高兴与你相遇!如果你喜欢本文内容,记得关注哦!
版权声明: 本文为 InfoQ 作者【poemyang】的原创文章。
原文链接:【http://xie.infoq.cn/article/23dc63ea535a41b46037d92fa】。文章转载请联系作者。
评论