祝你有美好的一天!
我们的 gRPC 服务遇到问题,我们希望这里的聪明人能够帮助我们了解发生了什么。
我们的情况是这样的:
我们有一个部署在 Azure 中的客户端服务(用 Java/Scala 编写,使用 java-grpc 1.18),它通过 gRPC 将连续的数据包流发送到部署在 AWS EKS 中的服务器服务(用 Java 编写,使用 java-grpc 1.20 并构建在 netty 4.1.3 之上),在配置了 Istio 的集群中。客户端每秒发送约 1K 请求(未使用流式传输)。
连接是通过与客户端一起部署的 NginX 代理建立的(进行一些路由。这里所有数据包都路由到 AWS 中的服务器),然后通过 IPSEC 隧道到达 EKS。在 EKS 中,连接首先通过 Istio IngressGateway,然后路由到 pod,其中通过 Envoy sidecar,然后到达 server。
在客户端,我们不断看到以下异常:
2020-10-26 18:33:39,748 [scala-execution-context-global-99] ERROR c.n.n.s.IngestionLayerForwardingService$ : Caught exception trying to send CLT message from device 256b2551-adc3-4f70-aa48-6b24d1b2436c to kafka-gateway
io.grpc.StatusRuntimeException: UNAVAILABLE: HTTP/2 error code: NO_ERROR
Received Goaway
at io.grpc.Status.asRuntimeException(Status.java:530)
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:482)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at io.grpc.internal.CensusStatsModule$StatsClientInterceptor$1$1.onClose(CensusStatsModule.java:699)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at io.grpc.internal.CensusTracingModule$TracingClientInterceptor$1$1.onClose(CensusTracingModule.java:397)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:459)
at io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:63)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:546)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$600(ClientCallImpl.java:467)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:584)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
这些错误发生在我们当前使用的 AWS 区域中来自 PROD 的约 0.1% 的流量中,但这个比率在其他区域是不同的(通常在其他区域较低,流量相同甚至更高)。
我们对 gRPC 和 Istio 的理解仍然很不完整,我们正在努力理解问题所在。
看起来服务器没有正确发出“double GOAWAY”,但我们在服务器端找不到任何 max_connection_age 的配置。
入口网关或 Envoy Sidecar 有可能发出自己的 GOAWAY 吗?它们会终止 gRPC 连接还是对 gRPC 完全透明?非常欢迎任何帮助或指向相关文档的指针:)
最仁慈, 安托万