长连接上的 Grpc 错误:Ping 过多

Grpc Error on Long Connections: Too Many Pings

我正在构建一个具有微服务架构的系统,该系统使用 grpc 在服务之间进行通信。我一开始有一个很长的 运行 请求,它到达一个中央端点,该端点向其他服务发出一堆请求。对中央服务的第一个请求依次等待,直到其他服务完成对它们的请求的计算,然后才会收到来自中央端点的响应。这可能需要几分钟才能完成。问题是我不断收到 grpc 错误,提示“Ping 太多”。我通过以下方式在我的 go 服务器上设置了 keepalive 参数:

ka_params := keepalive.ServerParameters{
        Time: 10 * time.Second,
        Timeout: 5 * time.Second,}

opts := []grpc.ServerOption{
    grpc.KeepaliveParams(ka_params),
}

s = grpc.NewServer(opts...)

在我的 python 服务器中是这样的:

opts = [("grpc.keepalive_time_ms", 10000), 
        ("grpc.keepalive_timeout_ms", 5000), 
        ("grpc.keepalive_permit_without_calls", True),
        ("grpc.http2.max_pings_without_data", 0)]
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), options=opts)

我不确定为什么我会收到太多 ping 错误。由于 keepalive,不是预期的 ping 吗?

我想我找到了解决办法。问题的症结在于 python 和 golang grpc 版本具有不同的默认设置,并且 python grpc 的文档非常少。

要解决此问题,您必须将 python 服务器上的 max_ping_strikes 设置为 0。python 服务器应具有以下选项:

opts = [("grpc.keepalive_time_ms", 10000), 
        ("grpc.keepalive_timeout_ms", 5000), 
        ("grpc.keepalive_permit_without_calls", True),
        ("grpc.http2.max_ping_strikes", 0)] 

在 python 服务器端,要配置可接受的保持活动时间段,您需要将“grpc.http2.min_ping_interval_without_data_ms”设置为 10 秒(考虑到网络延迟可能会高一些).

此参数的默认设置为 5 分钟,如果客户端每 10 秒发送一次 ping,则会导致发送带有“too_many_pings”的 GOAWAY 帧。

(此外,服务器端的“grpc.keepalive_time_ms”会导致服务器每 10 秒发送一次 keepalive ping。这可能不是您想要的。)

参考: https://github.com/grpc/grpc/blob/master/doc/keepalive.md