You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Sleuth迁移Micrometer Tracing后Gateway无Trace_ID问题

问题诊断与解决方案

你的核心问题是Gateway中Micrometer Tracing与原生OpenTelemetry依赖冲突,导致追踪上下文未正确初始化,同时WebFlux场景下Reactor Context与MDC的自动同步未生效,进而出现日志无traceId/spanId、Span.current()返回全0的情况。以下是针对性解决步骤:


1. 清理Gateway的依赖冲突

你在Gateway中同时引入了原生OpenTelemetry API/SDK和Micrometer Tracing Bridge OTel,两套追踪上下文机制共存会互相干扰。Micrometer Tracing Bridge OTel已封装必要的OpenTelemetry依赖,无需手动引入原生OTel包。

修改Gateway的依赖配置,删除以下内容:

implementation(group: 'io.opentelemetry', name: 'opentelemetry-api')
implementation(group: 'io.opentelemetry', name: 'opentelemetry-sdk')
implementation(group: 'io.opentelemetry', name: 'opentelemetry-exporter-logging')
implementation(group: 'io.opentelemetry', name: 'opentelemetry-semconv', version: '1.30.1-alpha')

仅保留common-tracing依赖即可,它已通过micrometer-tracing-bridge-otel提供桥接能力。


2. 确保WebFlux下Reactor Context与MDC自动同步

Spring Boot 3.x + Micrometer Tracing在WebFlux场景下,会自动通过TracingWebFilter初始化追踪Span,并通过ReactorContextMdcAutoConfiguration将Reactor Context中的追踪信息同步到MDC。无需手动设置MDC,只需确保依赖完整:

在common-tracing中确认包含WebFlux相关自动配置依赖(若Gateway为WebFlux项目,Spring Boot会自动引入,自定义库可显式添加):

api(group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '3.1.x') // 替换为你的Spring Boot版本

3. 调整自定义GlobalFilter的执行顺序

你的TraceContextGlobalFilter和TraceContextLoggingFilter可能在Micrometer的TracingWebFilter之前执行,此时追踪上下文尚未初始化,无法获取有效Span。

修改自定义Filter的执行顺序,确保在TracingWebFilter之后运行:

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

// TracingWebFilter默认顺序为Ordered.HIGHEST_PRECEDENCE + 10,自定义Filter设为其后的顺序
@Order(Ordered.HIGHEST_PRECEDENCE + 20)
public class TraceContextGlobalFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        // 此时已可通过Micrometer Tracer获取有效Span上下文
        return chain.filter(exchange);
    }
}

4. 正确获取Span上下文(避免直接调用OTel原生API)

WebFlux场景下,Span存储在Reactor Context中,不能直接在主线程调用Span.current()(OTel原生API),应使用Micrometer Tracing的Tracer API,并在Reactor序列中获取:

import io.micrometer.tracing.Tracer;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

@Component
public class SomeGatewayService {
    private final Tracer tracer;

    public SomeGatewayService(Tracer tracer) {
        this.tracer = tracer;
    }

    public Mono<Void> handleRequest() {
        return Mono.deferContextual(contextView -> {
            var currentSpan = tracer.currentSpan();
            if (currentSpan != null) {
                String traceId = currentSpan.context().traceId();
                String spanId = currentSpan.context().spanId();
                // 业务逻辑处理
            }
            return Mono.empty();
        });
    }
}

5. 验证日志格式与MDC键名

你的日志格式中%X{traceId:-}和%X{spanId:-}与Micrometer Tracing默认MDC键名一致,无需修改。建议移除opentelemetry-logback-mdc依赖,改用Micrometer原生的MDC同步机制,避免版本兼容问题:

// 移除OTel的MDC依赖
// runtimeOnly("io.opentelemetry.instrumentation:opentelemetry-logback-mdc-1.0:2.0.0-alpha")

6. 确认配置生效

检查Gateway的application.yml配置,确保追踪配置正确加载:

management:
  tracing:
    enabled: true
    sampling:
      probability: 1.0 # 确保100%采样
    propagation:
      type: tracecontext # 默认值,确保traceparent头正确解析传递

完成以上步骤后,Gateway的日志会自动输出traceId/spanId,Tracer.currentSpan()也能获取有效上下文,异常处理等场景会被自动覆盖,无需手动埋点。

内容的提问来源于stack exchange,提问作者wikenah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:27:48