Spring Sleuth Correlation-Id未在发起方服务A调度日志打印问题咨询
问题解答
你提到的手动调用MDC.put("Correlation-Id", cId)的方式是正确的,只要补充对应字段的清理逻辑即可。
现象原因
Sleuth 对 Baggage 字段和 MDC 的同步是有触发条件的:仅在HTTP/RPC请求的接收、发起阶段,会自动将Baggage字段同步到当前线程的MDC中。你的调度器逻辑运行在定时任务的独立线程中,手动更新BaggageField的值后,Sleuth不会主动将变更同步到当前线程的MDC,因此本地日志无法打印Correlation-Id。
而Feign调用发起时,Sleuth会将Baggage字段写入请求头传递到ServiceB,ServiceB接收请求时会自动将Baggage同步到本地MDC,所以下游服务可以正常打印该字段。
优化建议
手动设置MDC时一定要在任务结束后清除对应字段,避免定时任务线程池的线程复用导致ID串用,示例代码如下:
public void scheduleFixedDelayTask() { String cId = UUID.randomUUID().toString().replace("-", ""); BaggageField bField = BaggageField.getByName("Correlation-Id"); if (bField != null) { bField.updateValue(tracer.currentSpan().context(), cId); } MDC.put("Correlation-Id", cId); try { log.info("scheduleFixedDelayTask, {}", new Date()); List<Foo> foos = this.feignService.getData("foo"); log.info("scheduleFixedDelayTask - completed", new Date()); } finally { // 清理MDC字段,防止线程复用导致日志串号 MDC.remove("Correlation-Id"); } }
如果你不想手动操作MDC,也可以在更新Baggage字段后,调用Sleuth提供的CurrentTraceContext.Scope激活当前上下文,触发MDC自动同步,不需要手动维护MDC的增删。
内容的提问来源于stack exchange,提问作者user3145373 ツ
相关产品推荐
相关产品推荐

