Keepalive

如何在 gRPC 中使用基于 HTTP/2 PING 的 keepalive。

Keepalive

如何在 gRPC 中使用基于 HTTP/2 PING 的 keepalive。

概述

基于 HTTP/2 PING 的 keepalive 是一种保持 HTTP/2 连接活动的方式,即使没有数据传输。这是通过定期发送一个 PING 帧 到连接的另一端来完成的。HTTP/2 keepalive 可以提高 HTTP/2 连接的性能和可靠性,但仔细配置 keepalive 间隔非常重要。

背景

TCP keepalive 是一种众所周知的维护连接和检测断开连接的方法。当启用 TCP keepalive 时,连接的任何一方都可以发送冗余数据包。一旦被另一方确认,该连接将被视为良好。如果在多次尝试后未收到 ACK,则认为该连接已断开。

与 TCP keepalive 不同,gRPC 使用 HTTP/2,它提供了一个强制性的 PING 帧,可用于估计往返时间、带宽延迟乘积或测试连接。TCP keepalive 中的间隔和重试并不完全适用于 PING,因为传输是可靠的,因此在 gRPC 基于 PING 的 keepalive 实现中,它们被超时(相当于间隔 * 重试)所取代。

配置 keepalive 如何影响调用

对于快速回复的一元 RPC,不太可能触发 Keepalive。Keepalive 主要在存在长时间运行的 RPC 时触发,如果 keepalive 检查失败并且连接关闭,则该 RPC 将失败。

对于流式 RPC,如果连接关闭,任何正在进行的 RPC 将失败。如果调用正在流式传输数据,则流也将关闭,并且任何尚未发送的数据都将丢失。

keepalive 可能有用的常见情况

gRPC HTTP/2 keepalive 在各种情况下都很有用,包括但不限于

  • 通过可能被代理或负载均衡器视为空闲的长期连接发送数据时。
  • 当网络不太可靠时(例如,移动应用程序)。
  • 在长时间不活动后使用连接时。

Keepalive 配置规范

选项可用性描述客户端默认值服务器默认值
KEEPALIVE_TIME客户端和服务器PING 帧之间的间隔,以毫秒为单位。INT_MAX (禁用)7200000 (2 小时)
KEEPALIVE_TIMEOUT客户端和服务器PING 帧被确认的超时时间,以毫秒为单位。如果发送方在此时间内未收到确认,它将关闭连接。20000 (20 秒)20000 (20 秒)
KEEPALIVE_WITHOUT_CALLS客户端是否允许在没有任何未完成的流的情况下从客户端发送 keepalive ping。0 (false)不适用
PERMIT_KEEPALIVE_WITHOUT_CALLS服务器是否允许在没有任何未完成的流的情况下从客户端发送 keepalive ping。不适用0 (false)
PERMIT_KEEPALIVE_TIME服务器服务器在不发送任何数据/标头帧的情况下接收到连续 ping 帧之间的最小允许时间。不适用300000 (5 分钟)
MAX_CONNECTION_IDLE服务器通道可能没有未完成的 RPC 的最大时间,之后服务器将关闭连接。不适用INT_MAX (无限)
MAX_CONNECTION_AGE服务器通道可能存在的最大时间。不适用INT_MAX (无限)
MAX_CONNECTION_AGE_GRACE服务器通道达到最大年龄后的宽限期。不适用INT_MAX (无限)

语言指南和示例

语言示例文档
C++C++ 示例C++ 文档
GoGo 示例Go 文档
JavaJava 示例Java 文档
PythonPython 示例Python 文档

其他资源

上次修改时间 2024 年 10 月 9 日:添加 gRPC Keepalive Youtube 视频链接 (#1370) (79b65fd)