当前位置: 首页 > 知识库问答 >
问题:

gRPC:RPC调用上的随机取消异常

江凯风
2023-03-14

我偶尔得到取消错误时,调用gRPC方法。

以下是我的客户端代码(使用grpc java 1.22.0库):

public class MyClient {
    private static final Logger logger = LoggerFactory.getLogger(MyClient.class);
    private ManagedChannel channel; 
    private FooGrpc.FooStub fooStub;

    private final StreamObserver<Empty> responseObserver = new StreamObserver<>() {
        @Override
        public void onNext(Empty value) {
        }

        @Override
        public void onError(Throwable t) {
            logger.error("Error: ", t);
        }

        @Override
        public void onCompleted() {
        }
    };

    public MyClient() {
        this.channel = NettyChannelBuilder
            .forAddress(host, port)
            .sslContext(GrpcSslContexts.forClient().trustManager(certStream).build())
            .build();
        var pool = Executors.newCachedThreadPool(
                new ThreadFactoryBuilder().setNameFormat("foo-pool-%d").build());
        this.fooStub = FooGrpc.newStub(channel)
                .withExecutor(pool);
    }

    public void callFoo() {
        fooStub.withDeadlineAfter(500L, TimeUnit.MILLISECONDS)
                .myMethod(whatever, responseObserver);
    }
}

当我调用callFoo()方法时,它通常是有效的。客户端发送消息,服务器接收消息时不会出现问题。

但这个电话偶尔会给我一个错误:

io.grpc.StatusRuntimeException: CANCELLED: io.grpc.Context was cancelled without error
        at io.grpc.Status.asRuntimeException(Status.java:533) ~[handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onClose(ClientCalls.java:442) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.CensusStatsModule$StatsClientInterceptor$1$1.onClose(CensusStatsModule.java:700) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.CensusTracingModule$TracingClientInterceptor$1$1.onClose(CensusTracingModule.java:399) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:507) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:66) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:627) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$700(ClientCallImpl.java:515) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:686) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:675) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) [handler-0.0.1-SNAPSHOT.jar:?]
        at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) [handler-0.0.1-SNAPSHOT.jar:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]

奇怪的是,即使调用在客户端给出了一个错误,服务器还是会收到请求,大部分情况下。但有时服务器会错过它。

它甚至没有超过截止日期\u异常,它只是抛出取消:io。grpc。上下文被取消,没有出现错误。没有提供其他描述,因此我无法理解为什么会发生这种情况。

总结一下:

  1. 来自客户端的gRPC呼叫随机给出取消错误

共有1个答案

沈实
2023-03-14

GRPC-java支持自动截止日期和取消传播。当入站RPC导致出站RPC时,这些出站RPC继承入站RPC的截止日期。此外,如果取消入站RPC,则将取消出站RPC。

这是通过io实现的。grpc。上下文。如果你做了一个出站RPC,你想比入站RPC活得更长,你应该使用Context。fork()

public void myRpcMethod(Request req, StreamObserver<Response> observer) {
  // ctx has all the values as the current context, but
  // won't be cancelled
  Context ctx = Context.current().fork();
  // Set ctx as the current context within the Runnable
  ctx.run(() -> {
    // Can start asynchronous work here that will not
    // be cancelled when myRpcMethod returns
  });
  observer.onNext(generateReply());
  observer.onCompleted();
}
 类似资料:
  • 我想看看哪个随机数生成器包在我的神经网络中更快。 我目前正在更改github的一个代码,其中两个都是numpy。随机和随机包用于生成随机整数、随机选择、随机样本等。 我之所以更改此代码,是因为出于研究目的,我希望设置一个全局种子,以便能够比较超参数不同设置的精度性能。问题是,现在我必须为随机包和numpy包设置两个全局种子。理想情况下,我只想设置一个种子,因为来自两个随机数生成器序列的图形可能会更

  • 问题内容: 这是我正在尝试做的事情, 并且大多数时候我都成功了:基本上,我在网站上登录,然后等待一个类出现在源代码中,然后处理源代码。 我得到的例外: 这是代码: 我也尝试过这个: 我得到同样的例外。 我目前正在尝试: 我还没到失败的地步,我还在测试它。 抱歉,这很长。但是我想为这些随机超时找到一个pythonic干净的解决方案。 另一个可能也有帮助的信息:登录过程有时会很长,但是即使等待几分钟,

  • 我收到了一个错误,指出上传被用户取消了,并且在控制台中收到了三个错误(上传文件时来自firebase存储的都是相同的错误。我不知道在代码中是如何取消的(假设既然它声明它被用户取消了,那么它就在代码中)。 来自chrome控制台的完整错误:“Storage/canceled”代码:“Storage/canceled”消息:“Firebase Storage:User canceled The Upl

  • 问题内容: 我想在Java中获得1到50之间的随机值。 在的帮助下,我该怎么办;? 如何绑定返回的值? 问题答案: 第一种解决方案是使用类: 另一种解决方案是使用: 要么

  • 问题内容: 我有一个拥有大量下载量的应用程序,并且收到很多此错误消息: 正如您在堆栈跟踪中所看到的,其中没有一行包含我的代码跟踪。为了重现这一点,我很幸运地找到了一个使用Froyo(2.2 p7)的用户,而我只是向下滚动了代码中的s 之一。经过一些随机的时间后,它只是冻结了此异常。每次在不同的时间发生。 它后面有一个,只是增加了越来越多的行。显然,当我进行“过度滚动”时会收到此错误,但我什至无法想

  • 我不熟悉随机文件访问,我遇到了一个问题——据我所知,RandomAccessFile类提供了一个用于读/写的随机访问文件。我可以使用seek()方法移动到首选位置并开始阅读或写作,但在这种情况下并不重要。完全是随机访问吗?但在FileInputStream中,我有同样的能力 这种方法提供了我从某个特定的地方阅读。那么,有什么区别呢?(我猜,输入流读取所有文件,但只是通过断路位置之前的所有符号,但它