Java分布式链路追踪核心是traceId贯穿全链路,通过SLF4J+MDC实现:请求入口生成并存入MDC;日志格式嵌入%X{traceId:-NA};跨服务通过Header透传并重置MDC;异步场景需手动传递MDC上下文。

Java 中记录分布式链路追踪信息,核心是让一次请求的 traceId 贯穿所有服务节点,并在每条日志中自动携带。不依赖重量级 APM(如 SkyWalking),用 SLF4J + MDC 就能低成本落地。
生成并注入 traceId 到 MDC
每次 HTTP 请求进入网关或第一个服务时,生成全局唯一 ID(推荐雪花算法或 UUID),存入 SLF4J 的 MDC(Mapped Diagnostic Context)中:
- 用
org.slf4j.MDC.put("traceId", id)写入,后续同一线程内所有日志自动带上该字段 - 建议在 Filter 或 WebMvcConfigurer 的拦截器中统一处理,避免业务代码侵入
- 若使用 Spring Boot,可配合
@Order(Ordered.HIGHEST_PRECEDENCE)确保最早执行
配置日志输出格式,显式打印 traceId
在 Logback 配置(logback-spring.xml)中,把 MDC 字段嵌入 pattern:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 示例:
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [traceId:%X{traceId:-NA}] %msg%n -
%X{traceId:-NA}表示取 MDC 中 key 为 traceId 的值,缺失时显示 NA,防止空指针 - 结构化日志场景下,可用
logstash-logback-encoder输出 JSON,自动包含"traceId": "xxx"
跨服务透传 traceId
下游服务要继续使用同一个 traceId,需完成“传递 → 提取 → 存入 MDC”闭环:
立即学习“Java免费学习笔记(深入)”;
- 上游调用方:通过 HTTP Header(如
X-Trace-ID)或 Dubbo attachment 透传 - 下游接收方:在 Filter 或 Dubbo Filter 中读取 Header/attachment,再
MDC.put("traceId", ...) - 注意线程切换场景(如异步、CompletableFuture、@Async):MDC 不会自动继承,需手动
MDC.getCopyOfContextMap()传递并重置
补充关键细节
确保链路不中断,还要处理几个典型边界:
- 日志级别控制:生产环境关闭 DEBUG,避免 traceId 被刷屏淹没,但 INFO 及以上必须保留
- 异步任务兜底:对线程池提交的任务,包装 Runnable/Callable,捕获父线程 MDC 并初始化子线程
- 异常日志强化:
logger.error("xxx", e)会自动打印堆栈,traceId 已在 pattern 中,无需额外拼接 - 敏感信息脱敏:traceId 本身无敏感性,但若日志含用户 ID、手机号等,需在写入前脱敏

















