spring-cloud-gateway 集成 spring-cloud-sleuth 全链路后,traceId 不生效,无法获取 %X{traceId} 和 %X{spanId}
spring-cloud-gateway 集成 spring-cloud-sleuth 全链路后,traceId 不生效,无法获取 %X{traceId} 和 %X{spanId}
问题:
spring-cloud-gateway 升级到 2020.0.0-M6,spring-boot 升级到 2.4.0。 gateway集成 sleuth后,无法获取 %X{traceId} 和 %X{spanId}
说明: 下文 以 SCG 代码 spring-cloud-gateway。
SCG版本在 2020.0.0之前,即 spring-boot 在 2.1.x—2.3.x。 只要集成了sleuth后,可以正常获取链路ID的。但是升级到 2.4.0之后,就无法正常获取了。
通过查询官方文档,发现:https://docs.spring.io/spring-cloud-sleuth/docs/3.0.0-SNAPSHOT/reference/html/integrations.html#sleuth-reactor-integration
解释:
主要说在 2.4.0开始,sleuth通过 spring.sleuth.reactor.instrumentation-type 属性来控制
链路追踪上下文的侵入性。属性值有如下三个:
ON_EACH-用跟踪表示形式包装每个Reactor运算符。在大多数情况下,传递跟踪上下文。此模式可能会导致性能急剧下降。
ON_LAST-将最后一个Reactor运算符包装在跟踪表示中。在某些情况下传递跟踪上下文,因此访问MDC上下文可能不起作用。此模式可能会导致中等性能下降。
MANUAL-以最小侵入性的方式包装每个Reactor,而无需通过跟踪上下文。由用户决定。
由于向后兼容的原因,当前默认值是ON_EACH,但是我们鼓励用户迁移到手动插装,并从 WebFluxSleuthOperators 和
MessagingSleuthOperators 中获取,性能提升是非常大的。
既然,默认配置 是 ON_EACH,可是为什么 SCG 还是无法获取到 链路追踪ID呢?注:【除了 gateway,普通服务,是可以正常获取到的】
带着这个疑问,去spring-cloud/spring-cloud-sleuth 的 issues 搜索相关spring cloud gatewat 问题。确实还不少。如下:
主要,是画红框的 三个 lssues, 其中 第一 给出了答案:
意思:
核心意思说, 在2020.0.0后,sleuth默认将 SCG 的反应堆检测模式改为 manual,即手动获取。
目的: 是为了提高 webFlux 的性能。 因为在做 Spring Cloud Sleuth 性能测试时, webFlux + sleuth 的性能,相比 单独使用 webFlux 会大大的降低。
而 webMvc + sleuth 和单独使用 webMvc 的性能,几乎不受影响。 因此,在2.4.0后, 为了保证的 SCG 的性能, 将 反应堆检测模式默认为 manual,有别于 webMvc的 ON_EACH。
由此,答案算是找到了。 只需要将 SCG的 spring.sleuth.reactor.instrumentation-type 属性设置为 decorate_on_each 如下:
spring:
application:
name: @artifactId@
profiles:
active: dev
sleuth:
reactor:
#在2020.0.0中,已将默认网关反应器检测模式更改为manual,
#ON_EACH-用跟踪表示形式包装每个Reactor运算符。在大多数情况下,传递跟踪上下文。此模式可能会导致性能急剧下降。
#ON_LAST-将最后一个Reactor运算符包装在跟踪表示中。在某些情况下传递跟踪上下文,
#因此访问MDC上下文可能不起作用。此模式可能会导致中等性能下降。
#MANUAL-以最小侵入性的方式包装每个Reactor,而无需通过跟踪上下文。由用户决定
instrumentation-type: decorate_on_each
但是,为了保证 SCG的性能, 最好还是 遵守 官方的默认配置,使用手动方式。即将 instrumentation-type 设置为 manual。 然后通过如下方式,打印日志:
@SpringBootApplication
@RestController
@Slf4j
public class TestingGatewaySleuthApplication {
public static void main(String[] args) {
SpringApplication.run(TestingGatewaySleuthApplication.class, args);
}
@Autowired
Tracer tracer;
@Autowired
CurrentTraceContext currentTraceContext;
@GetMapping
public void logTest(ServerWebExchange exchange) {
WebFluxSleuthOperators.withSpanInScope(tracer, currentTraceContext, exchange, () -> log.error("TESTABCTEST"));
}
}
日志输入为:
2020-12-14 09:33:23.323 ERROR [,f79cf9596397093f,f79cf9596397093f] 35314 --- [or-http-epoll-2] s.s.t.TestingGatewaySleuthApplication : TESTABCTEST
更多推荐
所有评论(0)