ISTIO Sidecar导致Java grpc客户端在高并发负载下抛出“无法使用:上游连接错误或在标头之前断开连接/重置”

时间:2019-01-09 07:06:40

标签: java grpc istio grpc-java envoyproxy

我有两个gRPC服务,一个将通过普通的gRPC方法调用另一服务(两边都没有流),我使用istio作为服务网格,并将sidecar注入了这两个服务的kubernetes pod中。

gRPC调用在正常负载下正常工作,但是在高并发负载情况下,gRPC客户端不断抛出以下异常:

<#bef7313d> i.g.StatusRuntimeException: UNAVAILABLE: upstream connect error or disconnect/reset before headers
    at io.grpc.Status.asRuntimeException(Status.java:526)
    at i.g.s.ClientCalls$StreamObserverToCallListenerAdapter.onClose(ClientCalls.java:434)
    at i.g.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
    at i.g.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
    at i.g.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
    at i.g.i.CensusStatsModule$StatsClientInterceptor$1$1.onClose(CensusStatsModule.java:678)
    at i.g.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
    at i.g.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
    at i.g.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
    at i.g.i.CensusTracingModule$TracingClientInterceptor$1$1.onClose(CensusTracingModule.java:397)
    at i.g.i.ClientCallImpl.closeObserver(ClientCallImpl.java:459)
    at i.g.i.ClientCallImpl.access$300(ClientCallImpl.java:63)
    at i.g.i.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:546)
    at i.g.i.ClientCallImpl$ClientStreamListenerImpl.access$600(ClientCallImpl.java:467)
    at i.g.i.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:584)
    at i.g.i.ContextRunnable.run(ContextRunnable.java:37)
    at i.g.i.SerializingExecutor.run(SerializingExecutor.java:123)
    at j.u.c.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at j.u.c.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

与此同时,服务器端也没有例外,客户端pod的istio-proxy容器上也没有错误。但是,如果我禁用istio sidecar注入以使这两个服务直接相互通信,则不会出现此类错误。

有人可以告诉我为什么,以及如何解决这个问题吗?

非常感谢。

1 个答案:

答案 0 :(得分:1)

最后我找到了原因,这是由特使Sidecar的默认circuitBeakers设置,默认情况下的选项max_pending_requestsmax_requests设置为1024引起的。默认connecTimeout1s,因此在高并发负载情况下,当服务器端等待处理的待处理请求过多时,sidecar circuitBreaker会参与其中并告诉客户端,服务器端上游是{ {1}}。

要解决此问题,您需要为UNAVAILABLE设置合理的目标服务使用DestinationRule