GRPC-使用ContextPropagatingExecutorService和CurentConextExecutor

2022-04-03 00:00:00 grpc java grpc-java

由于GRPC在新线程上进行服务调用,并且GRPC上下文是线程本地的,我如何传播此GRPC上下文?我发现可以使用Conext.currentContextExecutor()和ConextPropagatingExecutorService,但我没有找到足够的资源或示例来支持这两个选项。有人能帮助实施这些吗?


解决方案

客户端侦听器不应更改应用程序看到的上下文实例。无论是使用阻塞、异步还是将来的存根,以及阻塞API将无法更改当前上下文,上下文行为都不应真正更改。

虽然拦截器可以自由地修改上下文中预先存在的(可变)值,但通常不需要这样做。通常,在每个RPC中创建一个新的拦截器实例并直接与拦截器通信,或通过自定义的CallOption进行通信更容易。

如果您只有一个需要访问响应头的调用站点,那么MetadataUtils.newCaptureMetadataInterceptor()是获取元数据的一种方便(尽管迂回)的方法。它是为测试而设计的,但适用于测试情况之外的小规模使用。

AtomicReference<Metadata> headers = new AtomicReference<>();
AtomicReference<Metadata> trailers = new AtomicReference<>();
// Using blocking for simplicity, but applies equally to futures
stub.withInterceptors(MetadataUtils.newCaptureMetadataInterceptor(headers, trailers))
    .someRpc();
Metadata headersSeen = headers.get();

如果需要从多个调用点访问相同的标头,最好创建一个执行所需操作的自定义侦听器。

CustomInterceptor interceptor = new CustomInterceptor();
stub.withInterceptors(interceptor)
    .someRpc();
... = interceptor.getWhateverValue();

这是在演示一个通用用例。特定实例通常可以进一步调整接口,使其更方便、更自然。

相关文章