Spring Boot3升级:从Sleuth迁移至Micrometer时替换WebFluxSleuthOperators
问题描述
我们正在将Spring Boot从2.x版本升级至3.x版本,但Spring Cloud Sleuth无法兼容Spring Boot 3。代码中多次使用WebFluxSleuthOperators类,迁移到Micrometer Tracing后找不到直接替代方案,现有迁移指南对该场景帮助有限。以下是相关代码:
import org.springframework.beans.factory.annotation.Autowired import org.springframework.cloud.sleuth.CurrentTraceContext import org.springframework.cloud.sleuth.Tracer import org.springframework.cloud.sleuth.instrument.web.WebFluxSleuthOperators import org.springframework.core.Ordered import org.springframework.stereotype.Component import org.springframework.web.server.ServerWebExchange import org.springframework.web.server.WebFilter import org.springframework.web.server.WebFilterChain import reactor.core.publisher.Mono @Component open class SleuthBaggageToResponseHeadersFilter( @Autowired private val tracer: Tracer, @Autowired private val currentTraceContext: CurrentTraceContext, ) : WebFilter, Ordered { override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> { exchange.response.beforeCommit { Mono.deferContextual { Mono.just(it) }.doOnNext { addToResponseHeaders(exchange) }.then() } return chain.filter(exchange) } private fun addToResponseHeaders(exchange: ServerWebExchange) = WebFluxSleuthOperators.withSpanInScope(tracer, currentTraceContext, exchange) { val requestId = tracer.getBaggage("REQUEST_ID")?.get() ?: "NOT_FOUND" exchange.response.headers.remove("REQUEST_ID") exchange.response.headers.add("REQUEST_ID", requestId) } override fun getOrder() = SleuthBaggageDefaultValuesFilter.ORDER + 1 }
替代方案
针对该场景,可通过以下方式完成Micrometer Tracing的适配:
1. 依赖调整
移除Spring Cloud Sleuth相关依赖,引入Micrometer Tracing的WebFlux适配依赖。例如使用Brave作为实现时,需引入:
micrometer-tracing-bridge-bravebrave-instrumentation-spring-webflux
2. 代码改造
Micrometer Tracing的Tracer与CurrentTraceContextAPI和Sleuth兼容度较高,无需借助专门的WebFlux工具类即可实现原有逻辑,改造后的代码如下:
import org.springframework.beans.factory.annotation.Autowired import org.springframework.core.Ordered import org.springframework.stereotype.Component import org.springframework.web.server.ServerWebExchange import org.springframework.web.server.WebFilter import org.springframework.web.server.WebFilterChain import reactor.core.publisher.Mono import io.micrometer.tracing.Tracer import io.micrometer.tracing.CurrentTraceContext @Component open class SleuthBaggageToResponseHeadersFilter( @Autowired private val tracer: Tracer, @Autowired private val currentTraceContext: CurrentTraceContext, ) : WebFilter, Ordered { override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> { exchange.response.beforeCommit { Mono.deferContextual { Mono.fromRunnable { addToResponseHeaders(exchange) } }.then() } return chain.filter(exchange) } private fun addToResponseHeaders(exchange: ServerWebExchange) { // 直接从当前Span获取Baggage val requestId = tracer.currentSpan()?.getBaggage("REQUEST_ID") ?: "NOT_FOUND" exchange.response.headers.remove("REQUEST_ID") exchange.response.headers.add("REQUEST_ID", requestId) } // 原SleuthBaggageDefaultValuesFilter.ORDER值为100,此处沿用原逻辑设为101 override fun getOrder() = 101 }
3. 关键逻辑说明
- Span与Baggage获取:Micrometer Tracing中
tracer.currentSpan()可直接获取当前上下文绑定的Span,无需WebFluxSleuthOperators做线程绑定。 - Scope手动管理:若需在非Reactor线程中操作Span,可使用
currentTraceContext.wrap(Runnable)或currentTraceContext.maybeScope(span)实现,等价于原withSpanInScope的作用。 - 过滤器顺序:原
SleuthBaggageDefaultValuesFilter.ORDER常量在Micrometer中不存在,直接使用原数值+1(100+1=101)即可保持原有执行顺序。
内容的提问来源于stack exchange,提问作者Clarence the Bard
相关产品推荐
相关产品推荐

