2016-01-20 153 views
2

我們正在使用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做出反應。我很高興它在這裏轉貼,以便我可以回答。 –

回答

2

每個回調都可以在不同的線程上調用,所以必須爲每個回調設置線程本地。看起來你可能會無意中獲得用於其他 RPC的上下文。

grpc-java 0.12.0應該在本週發佈。上下文已經部分集成在0.12.0中,我們還添加了Contexts.interceptCall(),這正是您所需要的:它爲每個回調附加和分離上下文。

在0.12.0中,您現在應該看到爲每個服務器調用(而不是ROOT)創建的新上下文以及從客戶端調用傳播到StreamObserver回調的上下文。

至於另注,不像ThreadLocalContext意在限定範圍:attach()後,你通常應該有一個嘗試,終於到detach()

+0

好的,非常感謝你,我拉下了代碼,看到了新的上下文類,並認爲這更接近我所需要的。十分感謝你分享這些信息。 – twreid

相關問題