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

从Spring Cloud Sleuth迁移到Micrometer Tracing后Brave Baggage失效

问题:Micrometer Tracing迁移后BaggageField无法同步到MDC

背景

Spring项目升级后收到系统提示:

您的项目设置不符合要求,原因:Spring Cloud Sleuth与此Spring Cloud版本不兼容,建议操作:从Spring Cloud Sleuth迁移到Micrometer Tracing。

随后移除Sleuth依赖,添加micrometer-tracing和micrometer-tracing-bridge-brave依赖,并配置了如下YAML:

management:
  tracing:
    enabled: true
    baggage:
      enabled: true
      correlation:
        enabled: true
        fields: USER_ID
      remote-fields: USER_ID

问题现象

迁移后,BaggageField无法像Sleuth时期那样自动同步到MDC中。排查发现调用BaggageField.updateValue()时,tracing.currentTraceContext().get()返回null,导致更新操作失效。

相关排查代码片段:

@Nullable static TraceContext currentTraceContext() {
    Tracing tracing = Tracing.current();
    return tracing != null ? tracing.currentTraceContext().get() : null;
}

现有配置与代码

Baggage配置类

import brave.baggage.BaggageField;
import brave.baggage.CorrelationScopeConfig;
import brave.context.slf4j.MDCScopeDecorator;
import brave.propagation.CurrentTraceContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BaggageConfig {

    public static final String USER_ID_KEY = "USER_ID";

    @Bean
    BaggageField userIdField() {
        return BaggageField.create(USER_ID_KEY);
    }
    

    @Bean
    public CurrentTraceContext.ScopeDecorator mdcScopeDecorator(BaggageField userIdField) {
        return MDCScopeDecorator.newBuilder()
                .clear()
                .add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(userIdField).flushOnUpdate().build())
                .build();
    }
}

注入并更新BaggageField

// 注入自定义的BaggageField
private final BaggageField userIdField;

// 更新字段值的代码
userIdField.updateValue(requestMetadataContext.getUserId());

使用的依赖版本

org.springframework.boot:3.0.6
org.springframework.cloud:spring-cloud-starter-bootstrap:4.0.2
org.springframework.cloud:spring-cloud-starter-consul-all:4.0.2
io.micrometer:micrometer-tracing:1.1.0
io.micrometer:micrometer-tracing-bridge-brave:1.1.0

解决方案

1. 问题根源

手动创建的BaggageField未被Micrometer Tracing的Brave桥接器纳入管理,无法关联到当前活跃的TraceContext;同时YAML配置中定义的USER_ID baggage字段会被自动生成实例,和自定义Bean产生冲突,导致上下文关联失效。

2. 具体修复步骤

步骤1:移除自定义的Baggage配置类

不需要手动创建BaggageField和MDCScopeDecorator,Micrometer Tracing会根据YAML配置自动生成这些组件,并自动处理MDC同步逻辑。直接删除BaggageConfig类即可。

步骤2:改用Micrometer官方API操作Baggage

替换手动注入的Brave原生BaggageField,使用Micrometer提供的Tracer或BaggageManager来获取和更新字段:

方式一:通过Tracer操作

import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.Baggage;

// 注入Tracer
private final Tracer tracer;

// 创建并更新USER_ID baggage
Baggage userIdBaggage = tracer.createBaggage("USER_ID");
userIdBaggage.set(requestMetadataContext.getUserId());

方式二:通过BaggageManager获取原生BaggageField
如果需要使用Brave原生API,可通过BaggageManager获取托管的实例:

import io.micrometer.tracing.BaggageManager;
import io.micrometer.tracing.brave.bridge.BraveBaggageField;
import brave.baggage.BaggageField;

// 注入BaggageManager
private final BaggageManager baggageManager;

// 获取托管的USER_ID字段
BaggageField userIdField = ((BraveBaggageField) baggageManager.getBaggageField("USER_ID")).delegate();

// 更新字段值
userIdField.updateValue(requestMetadataContext.getUserId());

步骤3:确保操作在活跃TraceContext上下文中执行

BaggageField.updateValue()需要在存在活跃TraceContext的线程中调用(如HTTP请求处理线程、被@Scheduled注解的定时任务线程等)。如果是在无TraceContext的线程中操作,需要手动创建上下文:

import brave.Tracing;
import brave.propagation.TraceContext;
import brave.propagation.CurrentTraceContext;

// 手动创建TraceContext并绑定到当前线程
TraceContext traceContext = Tracing.current().tracer().newTrace().context();
try (CurrentTraceContext.Scope scope = Tracing.current().currentTraceContext().newScope(traceContext)) {
    userIdField.updateValue(requestMetadataContext.getUserId());
}

3. 验证

修复完成后,USER_ID的值会自动同步到MDC,日志中可通过%X{USER_ID}直接打印该字段。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 15:37:06