Spring Boot应用间Jaeger未展示服务依赖问题求助
我来帮你梳理下这个问题的核心原因和解决办法:你遇到的单个服务Span正常但跨服务无依赖展示的情况,本质是跨REST调用时Trace上下文没有通过HTTP请求头传递——Jaeger需要调用方把Trace ID、Span ID等上下文信息注入请求头,被调用方再从请求头提取这些信息,才能把不同服务的Span串联成完整链路,进而展示服务依赖关系。
虽然你用的两个starter号称开箱即用,但在Spring Boot 2.1.x这个相对老旧的版本里,可能存在自动配置的兼容性问题,导致跨服务的Trace上下文传递没有自动生效。下面是具体的解决步骤:
一、先确保依赖配置正确
优先推荐使用opentracing-spring-jaeger-cloud-starter,它已经包含了opentracing-spring-web-starter的功能,还针对云原生场景做了优化,避免重复依赖冲突。注意选择和Spring Boot 2.1.x兼容的版本(比如2.0.0,适配Spring Boot 2.x系列):
<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId>opentracing-spring-jaeger-cloud-starter</artifactId> <version>2.0.0</version> </dependency>
二、手动配置Trace上下文传递(自动配置失效时)
如果自动配置没生效,我们可以手动实现拦截器和过滤器,强制完成Trace上下文的传递:
1. 调用方:配置RestTrace拦截器
创建RestTemplate的配置类,添加OpenTracing拦截器,让它自动把Trace信息注入到跨服务请求的头中:
import io.opentracing.Tracer; import io.opentracing.contrib.spring.web.client.TracingRestTemplateInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(Tracer tracer) { RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add(new TracingRestTemplateInterceptor(tracer)); return restTemplate; } }
重要提醒:必须使用这个配置类生成的RestTemplate发起跨服务请求,不能直接
new RestTemplate(),否则拦截器不会生效。
2. 被调用方:配置Trace请求过滤器
opentracing-spring-web-starter其实自带了TracingFilter,但如果自动配置没生效,可以手动注册这个过滤器,让它从请求头中提取Trace上下文:
import io.opentracing.contrib.spring.web.filter.TracingFilter; import io.opentracing.Tracer; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TracingFilterConfig { @Bean public FilterRegistrationBean<TracingFilter> tracingFilter(Tracer tracer) { FilterRegistrationBean<TracingFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new TracingFilter(tracer)); registrationBean.addUrlPatterns("/*"); registrationBean.setOrder(1); // 确保这个过滤器在其他业务过滤器之前执行,优先提取Trace信息 return registrationBean; } }
三、验证Jaeger与请求头
- Jaeger容器验证:你的all-in-one启动命令是完全正确的,确认容器正常运行,
14268(Span数据接收端口)和16686(UI端口)能正常访问。 - 请求头验证:发起跨服务请求时,检查请求头中是否包含
uber-trace-id字段——这是Jaeger的标准Trace头,里面包含了Trace ID、Span ID等关键信息,被调用方需要通过它来关联链路。
额外注意事项
- Spring Boot 2.1.x版本较老,建议尽量升级到稳定的新版本,新版本的OpenTracing和Jaeger Starter兼容性更好,自动配置的覆盖场景更全。
- 如果用Feign代替RestTemplate做跨服务调用,需要额外添加
opentracing-spring-cloud-feign-starter依赖,它会自动为Feign客户端添加Trace上下文传递支持。 - 确保每个服务的
spring.application.name配置正确,Jaeger UI会通过这个名称来标识不同的服务节点。
内容的提问来源于stack exchange,提问作者Xear

