如何在Spring Boot 1.5中集成Sleuth实现与2.2微服务的Trace ID传递
首先给你吃个定心丸:Spring Boot 1.5.x完全兼容Spring Cloud Sleuth 1.3.x——Sleuth 1.3.x属于Spring Cloud Edgware版本线,正是为Spring Boot 1.5.x量身打造的。你之前集成后没生成Trace ID,大概率是配置或初始化环节没踩对节奏,下面给你一步步讲正确的集成姿势,以及如何实现和Spring Boot 2.2微服务的无缝Trace ID传递。
1. 依赖配置(Maven为例)
首先确保你的项目引入正确的Spring Cloud和Sleuth依赖,版本必须对应Edgware线:
添加Spring Cloud版本管理
在pom.xml的dependencyManagement中加入:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.SR6</version> <!-- Edgware最后一个稳定版,兼容Spring Boot 1.5.2 --> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
引入Sleuth Starter
然后添加Sleuth的starter依赖(starter会自动配置所有核心组件,避免手动凑依赖的坑):
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> <version>1.3.5.RELEASE</version> </dependency>
2. 核心配置调整(对齐Spring Boot 2.2的Trace规则)
为了和Spring Boot 2.2的微服务无缝传递,需要让Sleuth 1.3.x的Trace/Span ID格式和2.x保持一致:
在application.properties或application.yml中添加:
# 开启Sleuth(默认是true,可显式配置确保生效) spring.sleuth.enabled=true # 生成16位Trace ID(和Spring Boot 2.x默认一致,2.x默认关闭128位) spring.sleuth.trace-id128=false # 生成8位Span ID(同样对齐2.x默认) spring.sleuth.span-id128=false # 允许Sleuth自动为HTTP请求、Feign/RestTemplate调用注入B3头 spring.sleuth.web.enabled=true
3. 替换自定义Filter,用Sleuth原生实现
你之前写的TransactionLoggingFilter可以完全替换掉——Sleuth自带的TraceFilter会自动完成:
- 解析上游传递的
X-B3-TraceId、X-B3-SpanId、X-B3-ParentSpanId头 - 如果没有上游Trace ID,自动生成符合规则的Trace/Span ID
- 将Trace/Span ID放入MDC,方便日志打印
- 请求结束后自动清理MDC
如果你的日志框架是Logback,记得在logback.xml的日志格式中加入Trace/Span ID,这样就能在日志里看到链路信息:
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %X{traceId} %X{spanId}%n</pattern>
4. 编程式创建Trace/Span(手动扩展链路)
如果你的单体应用中有非HTTP的业务链路(比如定时任务、异步方法),需要手动创建Span来延续链路,可以注入Sleuth的Tracer组件:
import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.Span; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class CustomBusinessService { @Autowired private Tracer tracer; public void executeAsyncTask() { // 手动创建并启动一个Span,指定操作名称 Span span = tracer.createSpan("async-task-execution"); try { // 给Span添加自定义标签(可选,用于链路追踪平台展示) tracer.addTag("task-type", "batch-processing"); // 你的业务逻辑代码 // ... } finally { // 必须关闭Span,避免内存泄漏 tracer.close(span); } } }
5. 和Spring Boot 2.2微服务的无缝传递
只要做到以下两点,就能实现完全无缝的Trace ID传递:
- 统一B3协议:Sleuth 1.3.x和2.x默认都使用B3格式的HTTP头传递Trace信息,不需要额外配置
- 统一ID格式:通过之前的
spring.sleuth.trace-id128=false配置,让两边的Trace ID都是16位,避免解析异常
如果单体应用需要调用Spring Boot 2.2的微服务:
- 使用
RestTemplate:Sleuth会自动拦截所有RestTemplate实例,在请求头中注入B3 Trace信息 - 使用
Feign:只要引入spring-cloud-starter-feign依赖,Sleuth会自动为Feign请求添加Trace头
6. 排查之前集成失败的常见原因
如果你之前集成后没生成Trace ID,大概率是以下问题:
- 没有引入
spring-cloud-starter-sleuth,只引入了sleuth-core:starter会自动配置TraceFilter、Tracer等核心组件,单独的core包不会自动初始化 - 自定义Filter优先级高于Sleuth的
TraceFilter:导致你的Filter先修改了MDC,覆盖了Sleuth生成的Trace ID,建议直接删除自定义Filter - 日志格式没配置
%X{traceId}:Trace ID已经生成,但你没在日志里打印出来,所以误以为没生成
注意事项
Spring Cloud Edgware版本已经停止官方维护,虽然能稳定运行,但如果长期来看,还是建议逐步规划单体应用的升级。不过在无法升级的当下,用Sleuth 1.3.x是完全可行的解决方案。
内容的提问来源于stack exchange,提问作者Federico Piazza

