[译] gRPC Connectivity Semantics and API

gRPC Connectivity Semantics and API

原文:https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md

本文主要描述 gRPC 通道的连接语义以及对 RPC 的相应影响,然后再探讨下 API。

States of Connectivity

gRPC Channels 提供了一种 clients 与 servers 交互的抽象。客户端的 channel 对象可以通过使用一个 DNS 名字多一点的信息就可以构建出来。Channels 封装了一系列功能,包括:名称解析、建立TCP连接(包括 retries 和 backoff)和 TLS 握手。
Channels 还可以处理已建立连接上的错误并重新连接,或者在 HTTP/2 GO_AWAY 的情况下,重新解析名称并重新连接。

为了对使用 gRPC API的用户(即应用程序代码)隐藏所有此活动的详细信息,同时暴露有关 channel 状态的有意义信息,我们使用了如下定义的五个状态表述的状态机:

CONNECTING:

标识该 channel 正在尝试建立连接,并且正在等待在 名称解析、TCP 连接建立 或 TLS 握手 中涉及的其中一个步骤上取得进展。它可以被用作创建 channel 时的初始状态。

READY:

标识该 channel 已经通过 TLS握手(或等效)和协议级(HTTP/2等)握手 成功建立了连接,并且所有后续的通信尝试都已成功(或者在没有任何已知故障的情况下等待)。

TRANSIENT_FAILURE:

标识该 channel 出现了一些瞬时故障(例如,TCP 3次握手超时 或 套接字错误)。处于此状态的 channel 最终将切换到 CONNECTING 状态并尝试再次建立连接。

由于重试是通过指数退避(exponential backoff)完成的,因此,连接失败的 channel 在刚开始时在此状态下花费很少的时间,但是随着重复尝试并失败的次数增加,channel 将在此状态下花费越来越多的时间。对于许多非致命故障(例如,由于服务器尚不可用而导致 TCP 连接尝试超时),channel 可能在该状态下花费越来越多的大量时间。

IDLE:

这个状态标识由于缺少新的(new)或未决(pending)的RPC,channel 甚至没有尝试创建连接。新的 RPC 可能会在这个状态被创建。任何在 channel 上启动 RPC 的尝试都会将通道从此状态推送到 CONNECTING 状态。

如果 channel 上已经在指定的 IDLE_TIMEOUT 时间内没有 RPC 活动,即在此期间没有新的(new)或挂起(pending)的(或活跃的) RPC,则 READY 或 CONNECTING 状态的 channel 将转换到 IDLE 状态。通常情况下,IDLE_TIMEOUT 的默认值是 300秒。

此外,已经接收到 GOAWAY 的 channel 在没有活跃(active)或挂起(pending)的 RPCs 时,也应当转换到 IDLE 状态,以避免尝试断开连接的服务器上的连接过载。

SHUTDOWN:

标识该 channel 已经开始关闭。任何新的 RPCs 都应该立即失败。待处理(pending)的 RPCs 可能会继续运行,直到应用程序取消它们。channel 可能会因为应用程序显式请求关闭,或者在尝试连接通信期间发生了不可恢复的错误而进入此状态。(截至2015年12月6日,没有已知的错误(连接或通信时)被归类为不可恢复的错误。)

一旦 channel 进入 SHUTDOWN 状态,就绝不会再离开。也就是说,SHUTDOWN 是状态机的结束。

状态转换表

下表列出了合法的状态转换和相关原因。空的单元表示不允许对应的状态转换。

From/To CONNECTING READY TRANSIENT_FAILURE IDLE SHUTDOWN
CONNECTING Incremental progress during connection establishment All steps needed to establish a connection succeeded Any failure in any of the steps needed to establish connection No RPC activity on channel for IDLE_TIMEOUT Shutdown triggered by application.
READY Incremental successful communication on established channel. Any failure encountered while expecting successful communication on established channel. No RPC activity on channel for IDLE_TIMEOUT OR upon receiving a GOAWAY while there are no pending RPCs. Shutdown triggered by application.
TRANSIENT_FAILURE Wait time required to implement (exponential) backoff is over. Shutdown triggered by application.
IDLE Any new RPC activity on the channel Shutdown triggered by application.
SHUTDOWN

Channel State API

所有的 gRPC 库都应该暴露一个 channel-level 的 API 方法以轮询 channel 的当前状态。

在 C++ 中, 这个方法叫 GetState,它会返回一个标识五个合法状态中一个的枚举值。如果 channel 当前处于 IDLE 状态,它还接受布尔值 try_to_connect 以转换为 CONNECTING。The boolean should act as if an RPC occurred, so it should also reset IDLE_TIMEOUT.
grpc_connectivity_state GetState(bool try_to_connect);

所有的 gRPC 库还应该暴露一个 API 以在当 channel 状态发生变化时,应用程序(使用 gRPC API 的用户)可以得到通知。由于状态更改可以快速并且与任何此类通知竞争,因此通知应该仅通知用户已经发生了一些状态改变,将其留给用户以轮询该通道以获得当前状态。异步版本的这个 API如下:
bool WaitForStateChange(grpc_connectivity_state source_state, gpr_timespec deadline);

当状态不是 source_state 时返回 true,如果截止时间到期则返回 false。Asynchronous- and futures-based 的API应该有一个相应的方法,允许在通道状态发生变化时通知应用程序。

请注意,每当从任何状态转换到任何其他状态时,都会发送通知。

也就是说,合法状态转换的规则要求从 CONNECTING 转换到 TRANSIENT_FAILURE 并返回到每个可恢复故障的 CONNECTING,即使相应的指数退避在重试之前不需要等待。综合效果是应用程序可能会收到看似虚假的状态更改通知。例如,在 CONNECTING 状态的 channel 上等待状态变更的应用程序,可能会在收到状态更改通知,但在轮询当前状态时发现其依然处于 CONNECTING 状态,因为该 channel 可能在 TRANSIENT_FAILURE 状态下花费了极少的时间。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351