2017-07-28 2 views
0

correlation-idが私の最初のマイクロサービスから2番目のマイクロサービスに伝播しないという問題があります。私は次のようにサーブレットフィルタ、コンテキストおよびコンテキスト・ホルダーを実装するために開始しました:相関IDの伝播が正常に行われない

@Component 
// Do not name bean "RequestContextFilter", otherwise filter will not work! 
public class CallContextFilter implements Filter { 

@Override 
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
     throws IOException, ServletException { 

    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;CallContextHolder.getContext().setCorrelationId(httpServletRequest.getHeader(CallContext.CORRELATION_ID)); 

    filterChain.doFilter(httpServletRequest, servletResponse); 
} 

@Override 
public void init(FilterConfig filterConfig) throws ServletException { 
} 

@Override 
public void destroy() { 
} 
} 

@Component 
@Getter 
@Setter 
public class CallContext { 
    public static final String CORRELATION_ID = "correlation-id"; 

    private String correlationId = new String(); 
} 

public class CallContextHolder { 

private static final ThreadLocal<CallContext> userContext = new ThreadLocal<>(); 

public static final CallContext getContext() { 
    CallContext context = userContext.get(); 

    if (context == null) { 
     context = new CallContext(); 
     userContext.set(context); 
    } 
    return userContext.get(); 
} 

} 

を次に、以下のように、私はRestTemplate Beanを実装:

@Bean 
public RestTemplate getRestTemplate() { 
    RestTemplate template = new RestTemplate(); 
    List<ClientHttpRequestInterceptor> interceptors = template.getInterceptors(); 
    interceptors.add(new CallContextInterceptor()); 
    return template; 
} 

インターセプタは次のようになります。

public class CallContextInterceptor implements ClientHttpRequestInterceptor { 

@Override 
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { 
    HttpHeaders headers = request.getHeaders(); 
    headers.add(CallContext.CORRELATION_ID, CallContextHolder.getContext().getCorrelationId()); 

    return execution.execute(request, body); 
} 
} 

エンドポイントを呼び出すと、サーブレットフィルタが実行され、相関IDがCallContextHolderに格納されます。ここまでは順調ですね。しかし、CallContextInterceptorは他のスレッドで呼び出されたようで、CallContextHolderのThreadLocal変数はnullです。私はこれを機能させるために何をしなければなりませんか?

@GetMapping("/ping") 
public String ping() { 
    return pongRestTemplateClient.getPong(); 
} 

答えて

0

問題は私がHysterixを使用していたことでした。 Hystrixはコードを実行するために新しいスレッドを生成し、 "外側の"スレッドコンテキストを完全に認識しません。したがって、実行中のスレッドは、Hysterixコマンドを使用するときに、ThreadLocalに依存する機能にアクセスできなくなります。

私はここに私の問題への答えを見つけた:https://github.com/jmnarloch/hystrix-context-spring-boot-starter

+0

スルース楽器ヒステリックスもあります。基本的に私たちが行ったことをコピーして、あなたが同じ仕事をやり直していることを理解できるようにします。 –

+0

私は数日後にスリーストを試してみるつもりです! –

関連する問題