You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何复用入站请求中的traceId以实现跨服务链路追踪?

跨服务Span追踪复用traceId解决方案

要实现跨服务的traceId复用,核心是在服务间调用时传递标准的追踪上下文头,并在下游服务初始化时解析这些头来构建Span上下文,让@NewSpan能基于上游的traceId生成子Span。以下是具体实现步骤:


一、统一追踪标准(选其一)

目前主流的跨服务追踪头标准有两种,上下游服务必须保持一致:

  • W3C Traceparent(推荐):格式为00-{traceId}-{spanId}-{flags},其中traceId是32位十六进制字符串,spanId是16位十六进制字符串
  • B3协议:使用X-B3-TraceId、X-B3-SpanId、X-B3-Sampled三个请求头

二、上游服务:传递追踪上下文

在调用下游服务时,将当前Span的上下文信息通过请求头传递出去,以Feign和RestTemplate为例:

1. Feign请求拦截器(自动传递头)

@Component
public class TracePropagationFeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        Span currentSpan = Span.current();
        SpanContext spanContext = currentSpan.getSpanContext();
        if (spanContext.isValid()) {
            // 传递W3C traceparent头
            String traceparent = String.format("00-%s-%s-01",
                    spanContext.getTraceId(),
                    spanContext.getSpanId());
            template.header("traceparent", traceparent);
            // 如果用B3协议,替换为以下代码:
            // template.header("X-B3-TraceId", spanContext.getTraceId());
            // template.header("X-B3-SpanId", spanContext.getSpanId());
            // template.header("X-B3-Sampled", "1");
        }
    }
}

2. RestTemplate拦截器

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getInterceptors().add((request, body, execution) -> {
            SpanContext spanContext = Span.current().getSpanContext();
            if (spanContext.isValid()) {
                request.getHeaders().add("traceparent",
                        String.format("00-%s-%s-01",
                                spanContext.getTraceId(),
                                spanContext.getSpanId()));
            }
            return execution.execute(request, body);
        });
        return restTemplate;
    }
}

三、下游服务:解析追踪上下文并初始化Span

通过过滤器拦截入站请求,解析传递的追踪头,手动构建Span上下文,确保@NewSpan执行前已有可用的traceId:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 确保过滤器最先执行
public class TraceContextInitFilter extends OncePerRequestFilter {
    private static final String TRACEPARENT_HEADER = "traceparent";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String traceparent = request.getHeader(TRACEPARENT_HEADER);
        if (traceparent != null && traceparent.matches("00-[a-f0-9]{32}-[a-f0-9]{16}-[a-f0-9]{2}")) {
            // 解析W3C traceparent头
            String[] parts = traceparent.split("-");
            String traceId = parts[1];
            String parentSpanId = parts[2];
            
            // 构建Span上下文
            SpanContext spanContext = SpanContext.create(
                    traceId,
                    parentSpanId,
                    TraceFlags.getSampled(),
                    TraceState.getDefault()
            );
            
            // 将父Span设置为当前上下文,后续@NewSpan会自动生成子Span
            Span parentSpan = Span.wrap(spanContext);
            try (Scope scope = parentSpan.makeCurrent()) {
                filterChain.doFilter(request, response);
            } finally {
                parentSpan.end();
            }
        } else {
            // 无有效追踪头时,走默认Span生成逻辑
            filterChain.doFilter(request, response);
        }
    }
}

四、简化方案:用Spring Cloud Sleuth自动处理

如果你的技术栈是Spring Cloud,可以直接引入Sleuth依赖,它会自动完成追踪头的传递和解析,无需手动写拦截器/过滤器:

  1. 引入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
  1. 配置文件指定追踪协议
spring:
  sleuth:
    propagation:
      type: W3C # 或B3,与上游保持一致

常见问题排查

  • 若之前手动预设请求头失败,大概率是头格式不符合标准,比如使用自定义头而非traceparent/X-B3系列,导致下游无法识别
  • 确保下游的过滤器执行顺序高于业务拦截器,保证Span上下文在@NewSpan注解执行前已初始化

内容的提问来源于stack exchange,提问作者Martin Valensky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 10:36:23