Search code examples
javaloggingmicroservicesthread-localmdc

Passing Correlation Id across Microservices requests: Which is the best strategy?


Suppose the sample scenario in which there's a Microservice X that have to call a Microservice Y. The need is to correlate subsequent calls with a Correlation-ID. Micoservices are Java (Spring Boot) based and expose REST and GRPC apis:

  1. "X ms" is called passing the Correlation-Id into the header.
  2. An interceptor in the "X ms" intercept the request and put "somewhere" (Ex. for JAVA in the MDC) the Correlation-Id
  3. The "X ms" Controller is triggered and delegate the execution of the business logic to a Service class method in the Business Layer.
  4. The Service class method does some stuff and call "Y ms" by loading the Correlation-Id from "somewhere"

enter image description here

What is the better place where store the context data (like the correlation-id) and why?

  1. Design methods with specific signatures in order to pass Context data between internal methods.
  2. Use the MDC.
  3. Use the ThreadLocal.
  4. Inject RequestContext where needed (for REST) or use Context (GRPC)
  5. Other

Thank you!


Solution

  • I would not use ThreadLocal or MDC (which is based on thread local) since it will lock you on implementation details if one day you will want to move to an event loop based service (for example using reactor / web-flux).

    You can propogate the context yourself in your method inside a Context object that will flow between your layers (from controller to business logic to DAL). The benefit here is that you are very explicit with this & this might be a bit more maintainable code.

    You can also considure looking into spring sleuth (that also integrates with zipkin). It is essentially based on MDC at it's core, but it should support reactor as well.