GRPC Java将数据从服务器拦截器传递到rpc服务调用

问题描述:

我们正在使用Java GRPC作为我们的内部服务之一,并且我们有一个服务器端拦截器,用于从头文件中获取信息并在日志记录环境中设置它们在内部使用ThreadLocal。GRPC Java将数据从服务器拦截器传递到rpc服务调用

因此,在我们的拦截器,我们做同样的事情到这一点:

LogMessageBuilder.setServiceName("some-service"); 

    final String someHeaderWeWant = headers.get(HEADER_KEY); 

    final LoggerContext.Builder loggingContextBuilder = new LoggerContext.Builder() 
     .someFieldFromHeaders(someHeaderWeWant); 
LoggerContext.setContext(loggingContextBuilder.build()); 
在我们的服务电话

然后我们进入这样的:

LoggingContext loggingContext = LoggingContext.getCurrent() 

但是目前情况下是空的某些时间。

然后,我们试图用GRPC Context类象下面这样:

LogMessageBuilder.setServiceName("some-service"); 

     final String someHeaderWeWant = headers.get(HEADER_KEY); 

     final LoggerContext.Builder loggingContextBuilder = new LoggerContext.Builder() 
      .someFieldFromHeaders(someHeaderWeWant); 
    Context.current().withValue(LOGGING_CONTEXT_KEY, loggingContextBuilder.build()).attach() 

然后访问它像服务电话:

LoggingContext context = LOGGING_CONTEXT_KEY.get(Context.current()) 

然而,这也是有时空,如果我打印出来内存地址看起来早在上下文始终是ROOT上下文,无论我是否在拦截器中附加,但经过几次调用后上下文都是正确的,并且记录器数据就像它应该那样。

因此,如果任何人有任何想法或更好的方式来传播数据从拦截器到服务调用,我很乐意听到它。

+0

我过去几天生病了,无法及时对IRC做出反应。我很高兴它在这里转贴,以便我可以回答。 –

每个回调都可以在不同的线程上调用,所以必须为每个回调设置线程本地。看起来你可能会无意中获得用于其他 RPC的上下文。

grpc-java 0.12.0应该在本周发布。上下文已经部分集成在0.12.0中,我们还添加了Contexts.interceptCall(),这正是您所需要的:它为每个回调附加和分离上下文。

在0.12.0中,您现在应该看到为每个服务器调用(而不是ROOT)创建的新上下文以及从客户端调用传播到StreamObserver回调的上下文。

至于另注,不像ThreadLocalContext意在限定范围:attach()后,你通常应该有一个尝试,终于到detach()

+0

好的,非常感谢你,我拉下了代码,看到了新的上下文类,并认为这更接近我所需要的。十分感谢你分享这些信息。 – twreid