62. 整合

62.1 OpenTracing

Spring Cloud Sleuth 与OpenTracing兼容。如果在 classpath 上有 OpenTracing,我们会自动注册 OpenTracing Tracer bean。如果要禁用此功能,请将spring.sleuth.opentracing.enabled设置为false

62.2 Runnable 和 Callable

如果将逻辑包装在RunnableCallable中,则可以将这些 class 包装在其 Sleuth 代表中,如下面_示例所示Runnable

Runnable runnable = new Runnable() {
	@Override
	public void run() {
		// do some work
	}

	@Override
	public String toString() {
		return "spanNameFromToStringMethod";
	}
};
// Manual `TraceRunnable` creation with explicit "calculateTax" Span name
Runnable traceRunnable = new TraceRunnable(tracing, spanNamer, runnable,
		"calculateTax");
// Wrapping `Runnable` with `Tracing`. That way the current span will be available
// in the thread of `Runnable`
Runnable traceRunnableFromTracer = tracing.currentTraceContext().wrap(runnable);

以下 example 显示了如何为Callable执行此操作:

Callable<String> callable = new Callable<String>() {
	@Override
	public String call() throws Exception {
		return someLogic();
	}

	@Override
	public String toString() {
		return "spanNameFromToStringMethod";
	}
};
// Manual `TraceCallable` creation with explicit "calculateTax" Span name
Callable<String> traceCallable = new TraceCallable<>(tracing, spanNamer, callable,
		"calculateTax");
// Wrapping `Callable` with `Tracing`. That way the current span will be available
// in the thread of `Callable`
Callable<String> traceCallableFromTracer = tracing.currentTraceContext().wrap(callable);

这样,您可以确保为每次执行创建并关闭新的 span。

62.3 Hystrix

62.3.1 自定义并发策略

我们注册了一个名为TraceCallable的自定义HystrixConcurrencyStrategy,它包含了 Sleuth 代表中的所有Callable实例。策略要么启动要么继续 span,具体取决于在调用 Hystrix 命令之前是否已经进行了跟踪。要禁用自定义 Hystrix 并发策略,请将spring.sleuth.hystrix.strategy.enabled设置为false

62.3.2 手动命令设置

假设您有以下HystrixCommand

HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
	@Override
	protected String run() throws Exception {
		return someLogic();
	}
};

要传递跟踪信息,您必须在HystrixCommand的 Sleuth version 中包含相同的逻辑,称为TraceCommand,如下面的 example 所示:

TraceCommand<String> traceCommand = new TraceCommand<String>(tracer, setter) {
	@Override
	public String doRun() throws Exception {
		return someLogic();
	}
};

62.4 RxJava

我们注册了一个自定义RxJavaSchedulersHook,它包含了 Sleuth 代表中的所有Action0实例,称为TraceAction。 hook 要么启动要么继续 span,具体取决于在安排 Action 之前是否已经进行了跟踪。要禁用自定义RxJavaSchedulersHook,请将spring.sleuth.rxjava.schedulers.hook.enabled设置为false

您可以为不希望创建 spans 的线程名称定义正则表达式列表。为此,请在spring.sleuth.rxjava.schedulers.ignoredthreads property 中提供 comma-separated 正则表达式列表。

reactive 编程和 Sleuth 的建议方法是使用 Reactor 支持。

62.5 HTTP integration

通过将property 设置为 value 等于false,可以禁用此部分的功能。

62.5.1 HTTP 过滤器

通过TracingFilter,所有采样的传入请求都会导致创建 Span。 Span 的 name 是http:请求发送的路径。例如,如果请求被发送到/this/that,那么 name 将是http:/this/that。您可以通过设置spring.sleuth.web.skipPattern property 来配置要跳过的 URI。如果在 classpath 上有ManagementServerProperties,的 value 会被附加到提供的 skip pattern。如果要重用 Sleuth 的默认跳过模式并只追加自己的跳过模式,请使用spring.sleuth.web.additionalSkipPattern传递这些模式。

要更改跟踪过滤器注册的 order,请设置spring.sleuth.web.filter-order property。

要禁用记录未捕获的 exceptions 的过滤器,可以禁用spring.sleuth.web.exception-throwing-filter-enabled property。

62.5.2 HandlerInterceptor

由于我们希望 span 名称是精确的,我们使用TraceHandlerInterceptor包装现有HandlerInterceptor或直接添加到现有HandlerInterceptors列表。 TraceHandlerInterceptor为给定的HttpServletRequest添加了一个特殊的请求属性。如果TracingFilter没有看到此属性,它会创建一个“fallback”span,这是在服务器端创建的附加 span,以便在 UI 中正确显示跟踪。如果发生这种情况,可能会丢失仪器。在这种情况下,请在 Spring Cloud Sleuth 中提交一个问题。

62.5.3 Async Servlet 支持

如果你的控制器返回CallableWebAsyncTask,Spring Cloud Sleuth 继续现有的 span 而不是 creating 一个新的 span。

62.5.4 WebFlux 支持

通过TraceWebFilter,所有采样的传入请求都会导致创建 Span。 Span 的 name 是http:请求发送的路径。例如,如果请求发送到/this/that,则 name 为http:/this/that。您可以使用spring.sleuth.web.skipPattern property 配置要跳过的 URI。如果在 classpath 上有ManagementServerProperties,的 value 会附加到提供的 skip pattern。如果要重用 Sleuth 的默认跳过模式并附加自己的跳过模式,请使用spring.sleuth.web.additionalSkipPattern传递这些模式。

要更改跟踪过滤器注册的 order,请设置spring.sleuth.web.filter-order property。

62.5.5 Dubbo RPC 支持

通过 Brave 的 integration,Spring Cloud Sleuth 支持达博。添加brave-instrumentation-dubbo-rpc依赖项就足够了:

<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-instrumentation-dubbo-rpc</artifactId>
</dependency>

您还需要设置包含以下内容的dubbo.properties文件:

dubbo.provider.filter=tracing
dubbo.consumer.filter=tracing

你可以阅读更多关于 Brave - Dubbo integration 这里的信息。可以找到 Spring Cloud Sleuth 和 Dubbo 的示例这里

62.6 HTTP Client Integration

62.6.1 同步 Rest Template

我们 inject 一个RestTemplate拦截器,以确保所有的跟踪信息都传递给请求。每次 time 调用,都会创建一个新的 Span。收到回复后会关闭。要阻止同步RestTemplate features,请将spring.sleuth.web.client.enabled设置为false

你必须将RestTemplate注册为 bean,以便拦截器被注入。如果使用new关键字创建RestTemplate实例,则检测不起作用。

62.6.2 异步 Rest Template

从 Sleuth 2.0.0开始,我们不再注册AsyncRestTemplate类型的 bean。由你来创建这样的 bean。然后我们检测它。

要阻止AsyncRestTemplate features,请将spring.sleuth.web.async.client.enabled设置为false。要禁用默认TraceAsyncClientHttpRequestFactoryWrapper的创建,请将spring.sleuth.web.async.client.factory.enabled设置为false。如果您根本不想创建AsyncRestClient,请将spring.sleuth.web.async.client.template.enabled设置为false

多个异步 Rest 模板

有时您需要使用 Asynchronous Rest Template 的多个 implementations。在以下代码段中,您可以看到如何设置此类自定义AsyncRestTemplate的示例:

@Configuration
@EnableAutoConfiguration
static class Config {

	@Bean(name = "customAsyncRestTemplate")
	public AsyncRestTemplate traceAsyncRestTemplate() {
		return new AsyncRestTemplate(asyncClientFactory(), clientHttpRequestFactory());
	}

	private ClientHttpRequestFactory clientHttpRequestFactory() {
		ClientHttpRequestFactory clientHttpRequestFactory = new CustomClientHttpRequestFactory();
		//CUSTOMIZE HERE
		return clientHttpRequestFactory;
	}

	private AsyncClientHttpRequestFactory asyncClientFactory() {
		AsyncClientHttpRequestFactory factory = new CustomAsyncClientHttpRequestFactory();
		//CUSTOMIZE HERE
		return factory;
	}
}

62.6.3 WebClient

我们 inject ExchangeFilterFunction implementation 创建一个 span,并通过 on-success 和 on-error 回调,负责关闭 client-side spans。

要阻止此 feature,请将spring.sleuth.web.client.enabled设置为false

您必须将WebClient注册为 bean,以便应用跟踪工具。如果使用new关键字创建WebClient实例,则检测不起作用。

62.6.4 Traverson

如果使用Traverson library,则可以作为由于RestTemplate已被截获,因此您可以完全支持 client 中的跟踪。以下伪 code 显示了如何执行此操作:

@Autowired RestTemplate restTemplate;

Traverson traverson = new Traverson(URI.create("http://some/address"),
    MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate);
// use Traverson

62.6.5 Apache HttpClientBuilder 和 HttpAsyncClientBuilder

我们检测HttpClientBuilderHttpAsyncClientBuilder,以便跟踪 context 被注入到已发送的请求中。

要阻止这些 features,请将spring.sleuth.web.client.enabled设置为false

62.6.6 Netty HttpClient

我们检测 Netty 的HttpClient

要阻止此 feature,请将spring.sleuth.web.client.enabled设置为false

您必须将HttpClient注册为 bean,以便进行检测。如果使用new关键字创建HttpClient实例,则检测不起作用。

62.6.7 UserInfoRestTemplateCustomizer

我们检测 Spring Security 的UserInfoRestTemplateCustomizer

要阻止此 feature,请将spring.sleuth.web.client.enabled设置为false

62.7 Feign

默认情况下,Spring Cloud Sleuth 通过TraceFeignClientAutoConfiguration提供 integration 与 Feign。您可以通过将spring.sleuth.feign.enabled设置为false来完全禁用它。如果这样做,则不会发生 Feign-related 检测。

Feign 检测的一部分是通过FeignBeanPostProcessor完成的。您可以通过将spring.sleuth.feign.processor.enabled设置为false来禁用它。如果将其设置为false,则 Spring Cloud Sleuth 不会检测任何自定义 Feign 组件。但是,所有默认检测仍然存在。

62.8 异步通信

62.8.1 @Async 带注释的方法

在 Spring Cloud Sleuth 中,我们检测 async-related 组件,以便在线程之间传递跟踪信息。您可以通过将spring.sleuth.async.enabled的 value 设置为false来禁用此行为。

如果使用@Async注释方法,我们会自动创建一个具有以下特征的新 Span:

  • 如果方法用@SpanName注释,则 annotation 的 value 是 Span 的 name。

  • 如果该方法未使用@SpanName注释,则 Span name 是带注释的方法 name。

  • span 用方法的 class name 和 method name 标记。

62.8.2 @Scheduled 带注释的方法

在 Spring Cloud Sleuth 中,我们检测预定的方法执行,以便在线程之间传递跟踪信息。您可以通过将spring.sleuth.scheduled.enabled的 value 设置为false来禁用此行为。

如果使用@Scheduled注释方法,我们会自动创建一个具有以下特征的新 span:

  • span name 是带注释的方法 name。

  • span 用方法的 class name 和 method name 标记。

如果要为某些@Scheduled带注释的 classes 跳过 span 创建,可以使用与@Scheduled带注释的 class 的完全限定 name 匹配的正则表达式设置spring.sleuth.scheduled.skipPattern。如果同时使用spring-cloud-sleuth-streamspring-cloud-netflix-hystrix-stream,则会为每个 Hystrix metrics 创建一个 span 并将其发送到 Zipkin。这种行为可能很烦人。这就是为什么,默认情况下,spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask

62.8.3 Executor,ExecutorService 和 ScheduledExecutorService

我们提供LazyTraceExecutorTraceableExecutorServiceTraceableScheduledExecutorService。这些 implementations 在每次 time 提交,调用或计划新任务时创建 spans。

以下 example 显示了在使用CompletableFuture时如何使用TraceableExecutorService传递跟踪信息:

CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> {
	// perform some logic
	return 1_000_000L;
}, new TraceableExecutorService(beanFactory, executorService,
		// 'calculateTax' explicitly names the span - this param is optional
		"calculateTax"));

Sleuth 无法使用parallelStream()开箱即用。如果要通过流传播跟踪信息,则必须使用supplyAsync(…)方法,如前所示。

执行者的自定义

有时,您需要设置AsyncExecutor的自定义实例。以下 example 显示了如何设置这样的自定义Executor

@Configuration
@EnableAutoConfiguration
@EnableAsync
static class CustomExecutorConfig extends AsyncConfigurerSupport {

	@Autowired BeanFactory beanFactory;

	@Override public Executor getAsyncExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		// CUSTOMIZE HERE
		executor.setCorePoolSize(7);
		executor.setMaxPoolSize(42);
		executor.setQueueCapacity(11);
		executor.setThreadNamePrefix("MyExecutor-");
		// DON'T FORGET TO INITIALIZE
		executor.initialize();
		return new LazyTraceExecutor(this.beanFactory, executor);
	}
}

62.9 消息

通过将property 设置为 value 等于false,可以禁用此部分的功能。

62.9.1 Spring Integration 和 Spring Cloud Stream

Spring Cloud Sleuth 与Spring Integration集成。它为发布和订阅 events 创建 spans。要禁用 Spring Integration 检测,请将spring.sleuth.integration.enabled设置为false

您可以提供spring.sleuth.integration.patterns pattern 以显式提供要包括在跟踪中的 channels 的名称。默认情况下,包括所有 channel 但hystrixStreamOutput channel。

使用Executor来 build Spring Integration IntegrationFlow时,必须使用Executor的未跟踪 version。使用TraceableExecutorService装饰 Spring Integration Executor Channel 会导致 spans 不正确关闭。

62.9.2 Spring RabbitMq

我们检测RabbitTemplate以便跟踪 headers 被注入到消息中。

要阻止此 feature,请将spring.sleuth.messaging.rabbit.enabled设置为false

62.9.3 Spring Kafka

我们检测 Spring Kafka 的ProducerFactoryConsumerFactory,以便跟踪 headers 被注入到创建的 Spring Kafka 的ProducerConsumer中。

要阻止此 feature,请将spring.sleuth.messaging.kafka.enabled设置为false

我们不支持通过@KafkaListener annotation 传播 context。检查此问题了解更多信息

62.10 Zuul

我们通过使用跟踪信息丰富 Ribbon 请求来检测 Zuul Ribbon integration。要禁用 Zuul 支持,请将spring.sleuth.zuul.enabled property 设置为false