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

Spring Cloud Sleuth整合RxJava2单请求生成多Trace问题求助

我来帮你解决这个RxJava并行调用导致多Trace的问题!在Spring Cloud Edgware.RELEASE版本里,Sleuth对RxJava的线程上下文传递支持确实有缺陷——当你用RxJava做并行调用时,每个新启动的线程都会丢失原来的Trace上下文,进而生成全新的Trace ID,这就是你看到单次请求出12条Trace的原因。下面是具体的修复方案:

问题本质

Edgware版本的Sleuth没有自动对RxJava的Scheduler做Trace上下文传播处理,并行操作时每个Observable的订阅线程都会重新生成Trace,导致同一个请求被拆成了多个独立的Trace链。

解决步骤

1. 自定义RxJava Hook传递Trace上下文

你需要注册一个RxJava的执行Hook,把当前请求的Trace Span上下文手动传递到RxJava的每个线程中。创建一个配置类:

import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import rx.Observable;
import rx.Subscriber;
import rx.plugins.RxJavaObservableExecutionHook;

@Configuration
public class SleuthRxJavaContextConfig {

    private final Tracer tracer;

    // 通过构造注入Tracer实例
    public SleuthRxJavaContextConfig(Tracer tracer) {
        this.tracer = tracer;
    }

    @Bean
    public RxJavaObservableExecutionHook sleuthRxJavaHook() {
        return new RxJavaObservableExecutionHook() {
            @Override
            public <T> Observable.OnSubscribe<T> onSubscribeStart(Observable<? extends T> observable, Observable.OnSubscribe<T> onSubscribe) {
                // 捕获当前请求的Trace Span
                Span currentSpan = tracer.getCurrentSpan();
                // 包装订阅逻辑,在新线程中恢复Span上下文
                return subscriber -> {
                    try (Tracer.SpanInScope scope = tracer.withSpan(currentSpan)) {
                        onSubscribe.call(subscriber);
                    }
                };
            }
        };
    }
}

2. 确保并行操作走Hook拦截逻辑

不管你用的是Observable.parallel()还是显式指定subscribeOn(Schedulers.io()),上面的Hook都会自动拦截Observable的订阅过程,把Trace上下文传递到新线程里。不需要额外修改你的业务代码,只需要让这个配置类被Spring扫描到即可。

3. 验证效果

重启服务后发起请求,去Zipkin后台查看Trace列表——现在单次请求应该只会生成1条Trace,所有RxJava并行调用的Span都会作为子Span挂在这条主Trace下面。

额外提示
  • Edgware是比较老的Spring Cloud版本了,后续的Finchley及更高版本对RxJava的上下文传递做了原生支持,升级版本的话这个问题会自动消失。
  • 如果你用的是RxJava 2.x,上面的代码需要调整为RxJava 2对应的Hook(比如RxJavaPlugins.setObservableAssemblyHook()),不过Edgware版本默认适配的是RxJava 1.x,所以上面的代码应该刚好匹配你的场景。

内容的提问来源于stack exchange,提问作者Ankit Bansal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:48:08