如何通过Micrometer Tracing按正则f-.*动态传播下游请求头?
解决方案
技术栈
- Spring Boot 3.3.+
io.micrometer:micrometer-tracing-bridge-brave
问题背景
默认通过management.tracing.baggage.remote-fields=f-user只能指定单个请求头传播,无法通过正则f-.*批量匹配所有以f-开头的请求头,需要自定义Brave链路追踪配置实现。
实现步骤
1. 自定义链路追踪配置类
创建配置类,通过TracingCustomizer配置Brave的Baggage传播规则,支持正则匹配请求头:
import brave.baggage.BaggageField; import brave.baggage.BaggagePropagation; import brave.baggage.BaggagePropagationConfig; import brave.baggage.CorrelationScopeConfig; import brave.baggage.CorrelationScopeCustomizer; import brave.TracingCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TraceBaggageConfig { @Bean public TracingCustomizer tracingBaggageCustomizer() { return tracingBuilder -> { // 配置传播所有以f-开头的请求头 BaggagePropagationConfig regexBaggageConfig = BaggagePropagationConfig.newBuilder(BaggageField.create("f-.*")) .addKeyNamePattern("f-.*") .build(); tracingBuilder.baggagePropagation( BaggagePropagation.newBuilder(BaggagePropagation.defaultConfig()) .add(regexBaggageConfig) .build() ); }; } // 可选:将匹配的请求头同步到MDC(需注意异步任务上下文传递) @Bean public CorrelationScopeCustomizer mdcCorrelationCustomizer() { return scopeBuilder -> { scopeBuilder.add( CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageField.create("f-.*")) .namePattern("f-.*") .build() ); }; } }
2. 配置MDC同步(可选)
如果需要将这些请求头字段同步到MDC,在application.properties中开启关联配置:
management.tracing.baggage.correlation.enabled=true
3. 异步任务上下文传递(针对MDC场景)
若存在异步任务,需自定义线程池传递MDC上下文,避免线程切换丢失数据:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.Map; import java.util.concurrent.Executor; @Configuration public class AsyncTaskConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); executor.setThreadNamePrefix("Async-Trace-"); executor.initialize(); // 包装线程池,传递MDC上下文 return runnable -> { Map<String, String> mdcContext = org.slf4j.MDC.getCopyOfContextMap(); executor.execute(() -> { try { if (mdcContext != null) { org.slf4j.MDC.setContextMap(mdcContext); } runnable.run(); } finally { org.slf4j.MDC.clear(); } }); }; } }
说明
- 原生
management.tracing.baggage.remote-fields仅支持具体字段名,不支持正则,因此必须通过自定义Brave的BaggagePropagation配置实现批量匹配。 - MDC本身非线程安全,异步场景下必须通过线程池包装传递上下文,否则会出现数据丢失或串线问题。
内容的提问来源于stack exchange,提问作者Artem Ptushkin
相关产品推荐
相关产品推荐

