Brave BaggageField设置值后获取返回null问题求助
Brave BaggageField 设置后获取值为 null 的问题排查与解决
核心问题原因
- 版本兼容性冲突:你使用的Spring Boot 3.3.4对应Spring Cloud 2023.0.x(Leyton)版本,但
spring-cloud-starter-sleuth 3.0.2是适配Spring Boot 2.7.x的旧版本,版本不匹配会导致Trace上下文与Baggage的绑定逻辑异常。 - BaggageField未预先注册:Sleuth基于Brave实现,要求所有要使用的BaggageField必须预先注册到Trace上下文配置中,直接调用
BaggageField.create()创建的实例无法被上下文识别,设置的值无法存入Trace的Baggage存储。 - 响应式上下文未正确关联:在Reactor响应式环境中,Baggage上下文绑定到Reactor Context,直接在Mono/Flux链外调用
updateValue无法将值写入正确的上下文。
解决方案
1. 修正版本兼容性
将Sleuth版本替换为适配Spring Boot 3.3.4的版本,推荐使用Spring Cloud依赖管理自动适配:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2023.0.4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> </dependencies>
2. 预先注册BaggageField
有两种注册方式,任选其一即可:
方式一:配置文件注册(推荐)
在application.yml中添加以下配置,注册需要使用的Baggage字段:
spring: sleuth: baggage: # 如果需要跨服务传递这些字段,配置remote-fields;仅本地使用则配置local-fields remote-fields: appType,cdrCategory,idNumber,connectionNumber,appLanguage,mifeTraceId local-fields: appType,cdrCategory,idNumber,connectionNumber,appLanguage,mifeTraceId
方式二:Java配置类注册
创建配置类手动注册BaggageField,并关联响应式上下文:
import brave.baggage.BaggageField; import brave.baggage.BaggagePropagationConfig; import brave.context.r2dbc.ReactorBaggageCorrelation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SleuthBaggageConfig { // 定义全局可复用的BaggageField实例 public static final BaggageField APP_TYPE = BaggageField.create("appType"); public static final BaggageField CDR_CATEGORY = BaggageField.create("cdrCategory"); public static final BaggageField ID_NUMBER = BaggageField.create("idNumber"); public static final BaggageField CONNECTION_NUMBER = BaggageField.create("connectionNumber"); public static final BaggageField APP_LANGUAGE = BaggageField.create("appLanguage"); public static final BaggageField MIFE_TRACE_ID = BaggageField.create("mifeTraceId"); @Bean public BaggagePropagationConfig baggagePropagationConfig() { return BaggagePropagationConfig.newBuilder() .add(APP_TYPE) .add(CDR_CATEGORY) .add(ID_NUMBER) .add(CONNECTION_NUMBER) .add(APP_LANGUAGE) .add(MIFE_TRACE_ID) .build(); } // 响应式环境必须配置,关联Reactor Context与Baggage @Bean public ReactorBaggageCorrelation reactorBaggageCorrelation() { return ReactorBaggageCorrelation.create(APP_TYPE, CDR_CATEGORY, ID_NUMBER, CONNECTION_NUMBER, APP_LANGUAGE, MIFE_TRACE_ID); } }
3. 正确设置与获取Baggage值
在响应式环境中,必须确保在Reactor链内操作Baggage:
设置值并验证
import static com.yourpackage.SleuthBaggageConfig.*; import org.springframework.util.ObjectUtils; // 在Mono/Flux链中设置值并验证 Mono.just(requestEntity) .doOnNext(entity -> { APP_TYPE.updateValue(ObjectUtils.isEmpty(entity.getAppType()) ? "-" : entity.getAppType()); CDR_CATEGORY.updateValue(ObjectUtils.isEmpty(entity.getCdrCategory()) ? "-" : entity.getCdrCategory()); ID_NUMBER.updateValue(ObjectUtils.isEmpty(entity.getIdNumber()) ? "-" : entity.getIdNumber()); CONNECTION_NUMBER.updateValue(ObjectUtils.isEmpty(entity.getConnectionNumber()) ? "-" : entity.getConnectionNumber()); APP_LANGUAGE.updateValue(ObjectUtils.isEmpty(entity.getAppLanguage()) ? "-" : entity.getAppLanguage()); MIFE_TRACE_ID.updateValue(entity.getTraceId()); }) .then(Mono.deferContextual(ctx -> { // 获取并验证值 String traceId = MIFE_TRACE_ID.getValue(); log.error("VA_FIXES mifeTraceId in reactive context: {}", traceId); return Mono.empty(); })) .subscribe();
非响应式环境或需要临时作用域
使用BaggageInScope确保值在指定作用域内有效:
try (BaggageInScope scope = MIFE_TRACE_ID.newScope(requestEntity.getTraceId())) { String traceId = MIFE_TRACE_ID.getValue(); log.error("VA_FIXES mifeTraceId: {}", traceId); }
验证效果
完成上述配置后,重新启动服务,调用接口即可看到Baggage值能正常设置和获取。
内容的提问来源于stack exchange,提问作者Hashini Udara
相关产品推荐
相关产品推荐

