go学习

gRPC Guide

2017-08-08  本文已影响472人  不智鱼

最近项目需要用到 gRPC,网上gRPC 的资料较少,翻译了官网的 gRPC guide 文档,以供组内学习,部分暂时用不到的部分未进行翻译。

gRPC Guide


该文档主要介绍 gRPC 和 protocol buffers。 gRPC 使用 protocol buffers 作为 IDL 和消息交换格式。本文档适合与刚接触 gRPC 或者 protocol buffers 的初学者。

概述


gRPC client 可以直接像调用本地方法一样调用 server 的方法,这使得开发分布式应用和服务变得更加简单。和很多其他 RPC 框架一样,gRPC 通过指定方法调用的参数和返回值来定义服务。server 实现 RPC 接口,处理客户端的调用请求。client 提供和 server 一样的接口。

gRPC client 和 server 可以在不同的环境运行和通信,比如 Google 内部的服务器到你的桌面应用。client 和 server 的语言可以是任何 gRPC 支持的语言,你可以用 C++ 来实现 server, 用 java 和 ruby 来实现 client。另外最新的 Google API 都提供了 gRPC 接口,来帮助你在应用中更便捷的使用 Google 提供的功能。

Working with Protocl Buffers


gRPC 默认使用 Protocol buffers,这是一个 google 开源的成熟的数据序列化机制。接下来会简单介绍一下它是如何工作的。

使用 protocol buffers 前需要先将你要序列化的结构化数据定义为 .proto 文件。protocol buffers 通过 messages 定义数据结构,每个 message 由一系列属性组成,类似于类的定义,我们可以看一个简单的例子

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

定义好数据结构后,可以使用 protocol buffers 编译器(protoc)将其生成其他语言的类。这些类提供所有属性的访问方法,及序列化和反序列方法。例如,你使用的是 C++,运行编译器会生成一个 Person 类,你可以在在你的应用中实例化或序列化来传输这些 protocol buffers 信息。

除了数据结构外,你还可以在 .proto 文件中定义 gRPC 服务,包括服务接口的参数和返回类型。例如:

// 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;
}

和正常使用 protocol buffers 不一样, gRPC 可以使用 protoc 的 gRPC 插件生成代码,除了会生成共传播和序列化的类以外,还会生成 gRPC client 和 server 代码。

protocol buffers 版本


建议使用 proto3 版本的 protocol buffers,语法更简洁,支持更多语言。

基本概念


服务定义

之前已经提到了,gRPC 的基于 protocol buffers 定义服务。所谓定义服务,就是使用 IDL 来描述你的服务接口和传输消息结构。gRPC 使用 protocol buffers 作为 IDL。

gRPC 支持四种类型的服务方法

rpc SayHello(HelloRequest) returns (HelloResponse){
}
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
}
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
}
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
}

API 使用

gRPC 使用 .proto 生成 client 和 server 代码及 API。client 调用这些 API, server 实现这些API。

同步 VS 异步

同步 RPC 调用在 server 的响应到达之前会阻塞,这是 RPC 的常用使用方式。另一方面,web 服务在很多场景下天然是异步的,因此异步的 RPC 也经常使用,异步 RPC 调用不会阻塞当前线程。

gRPC 的同步和异步调用完全依赖用户自身的代码处理。

RPC life cycle

简单 RPC

流式 RPC

Deadline / timeout

gRPC 允许 client 设置过期时间,超过过期时间 RPC 会被中止,并返回 DEADLINE_EXCEEDED 错误。。同时 server 可以查看某个 RPC 是否超时,或者还有多长时间超时。

deadline 或者 timeout 在不同语言的 API 可能不一样,不一定都提供, deadline = timeout + now。

RPC 中断

在 gRPC 中,client 和 server 都可以独自决定一次调用是否成功,并且结论可能不一致。这也就意味,server 可能认为 RPC 已经成功了,但是 client 认为失败了(比如超时)。甚至 server 可以在 client 还未将 request 完全发送完就结束一次调用。

Metadata

Metadata 元数据使用 kv 对表示某个特定 RPC 调用的信息,key 是字符串,values 通常也是字符串,也可以是二进制数据。元数据对于 gRPC 本身是不透明的,它提供了使 client 与 server 端调用关联起来的信息。

通道 (Channels)

创建 client 时,gRPC 的通道提供了和某个特定 host 及 port 的 gRPC server 之间的连接。clietn 可以通过参数改变 gRPC 的默认欣慰,比如消息压缩开关等。通道是有状态的,包括 connectedidle

如何处理关闭的通道不同语言不太一样。有的语言甚至不提供通道状态查询。

鉴权


可通过 TSL 或 Token 的方式进行鉴权。

HTTP2


gRPC 是基于 HTTP2

Request:

HEADERS (flags = END_HEADERS)
:method = POST
:scheme = http
:path = /google.pubsub.v2.PublisherService/CreateTopic
:authority = pubsub.googleapis.com
grpc-timeout = 1S
content-type = application/grpc+proto
grpc-encoding = gzip
authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v

DATA (flags = END_STREAM)
<Delimited Message>

Response

HEADERS (flags = END_HEADERS)
:status = 200
grpc-encoding = gzip

DATA
<Delimited Message>

HEADERS (flags = END_STREAM, END_HEADERS)
grpc-status = 0 # OK
trace-proto-bin = jher831yy13JHy3hc

错误处理


错误模型

我们之前看到的信息都是 server 返回状态正常 OK 时的情况,如果调用不成功会发生什么呢?

当错误发生时,gRPC 会返回状态码,也可能会包括一些错误的描述信息。

错误状态码

gRPC 会在很多情况下产生错误,包括网络失败,鉴权失败等,这些错误都会伴随一个状态码,所有语言的状态码都是统一的。

通用错误

描述 状态码
client 取消请求 GRPC_STATUS_CANCELLED
超时 GRPC_STATUS_DEADLINE_EXCEEDED
server 端未找到对应方法 GRPC_STATUS_UNIMPLEMENTED
server 已关闭 GRPC_STATUS_UNAVAILABLE
server 内部错误 GRPC_STATUS_UNKNOWN

网络错误

描述 状态码
在deadline 之前没有数据传回 GRPC_STATUS_DEADLINE_EXCEEDED
在连接破坏前,有一部分数据传回 GRPC_STATUS_UNAVAILABLE

协议错误

描述 状态码
压缩算法不支持 GRPC_STATUS_INTERNAL
client 使用的压缩机制 server 不支持 GRPC_STATUS_UNIMPLEMENTED
流量超过限制 GRPC_STATUS_RESOURCE_EXHAUSTED
违反流量控制协议 GRPC_STATUS_INTERNAL
未知的返回状态 GRPC_STATUS_UNKNOWN
未授权 GRPC_STATUS_UNAUTHENTICATED
protocol buffer 解析失败 GRPC_STATUS_INTERNAL
上一篇下一篇

猜你喜欢

热点阅读