64. Integrations

64.1 OpenTracing

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

64.2 可运行和可调用

如果将逻辑包装在RunnableCallable中,则可以将这些类包装在其 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(this.tracing, spanNamer, runnable,
		"calculateTax");
// Wrapping `Runnable` with `Tracing`. That way the current span will be available
// in the thread of `Runnable`
Runnable traceRunnableFromTracer = this.tracing.currentTraceContext()
		.wrap(runnable);

以下示例显示了针对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<>(this.tracing, spanNamer,
		callable, "calculateTax");
// Wrapping `Callable` with `Tracing`. That way the current span will be available
// in the thread of `Callable`
Callable<String> traceCallableFromTracer = this.tracing.currentTraceContext()
		.wrap(callable);

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

64.3 Hystrix

64.3.1 自定义并发策略

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

64.3.2 手动命令设置

假设您具有以下HystrixCommand

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

要传递跟踪信息,必须在 Sleuth 版本的HystrixCommand(称为TraceCommand)中包装相同的逻辑,如以下示例所示:

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

64.4 RxJava

我们注册了一个自定义RxJavaSchedulersHook,该自定义RxJavaSchedulersHook将所有Action0实例包装在其 Sleuth 代表中,称为TraceAction。钩子将开始或 continueSpan,具体取决于在计划操作之前是否已经进行了跟踪。要禁用自定义RxJavaSchedulersHook,请将spring.sleuth.rxjava.schedulers.hook.enabled设置为false

您可以为不想创建 Span 的线程名称定义一个正则表达式列表。为此,请在spring.sleuth.rxjava.schedulers.ignoredthreads属性中提供以逗号分隔的正则表达式列表。

Tip

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

64.5 HTTP 集成

可以通过将spring.sleuth.web.enabled属性设置为false来禁用此部分的功能。

64.5.1 HTTP filter

通过TracingFilter,所有采样的传入请求都将创建 Span。 Span 的名称是http:请求发送到的路径。例如,如果请求已发送到/this/that,则名称将为http:/this/that。您可以通过设置spring.sleuth.web.skipPattern属性来配置要跳过的 URI。如果在 Classpath 上有ManagementServerProperties,则其contextPath的值将附加到提供的跳过模式中。如果要重用 Sleuth 的默认跳过模式并追加自己的模式,请使用spring.sleuth.web.additionalSkipPattern传递这些模式。

要更改跟踪filter注册的 Sequences,请设置spring.sleuth.web.filter-order属性。

要禁用记录未捕获异常的filter,可以禁用spring.sleuth.web.exception-throwing-filter-enabled属性。

64.5.2 HandlerInterceptor

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

64.5.3 异步 Servlet 支持

如果您的控制器返回CallableWebAsyncTask,则 Spring Cloud Sleuth 会 continue 现有范围,而不是创建一个新范围。

64.5.4 WebFlux 支持

通过TraceWebFilter,所有采样的传入请求都将导致 Span 的创建。 Span 的名称是http:请求发送到的路径。例如,如果请求已发送到/this/that,则名称为http:/this/that。您可以使用spring.sleuth.web.skipPattern属性配置要跳过的 URI。如果 Classpath 上有ManagementServerProperties,则其contextPath的值将附加到提供的跳过模式中。如果要重用 Sleuth 的默认跳过模式并追加自己的模式,请使用spring.sleuth.web.additionalSkipPattern传递这些模式。

要更改跟踪filter注册的 Sequences,请设置spring.sleuth.web.filter-order属性。

64.5.5 Dubbo RPC 支持

通过与 Brave 的集成,Spring Cloud Sleuth 支持Dubbo。添加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 集成here的更多信息。可以找到here作为 Spring Cloud Sleuth 和 Dubbo 的示例。

64.6 HTTPClient 端集成

64.6.1 同步 Rest Template

我们注入了RestTemplate拦截器,以确保所有跟踪信息都传递给请求。每次拨打电话时,都会创建一个新的 Span。收到响应后关闭。要阻止同步RestTemplate功能,请将spring.sleuth.web.client.enabled设置为false

Tip

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

64.6.2 异步 Rest Template

Tip

从 Sleuth 2.0.0开始,我们不再注册AsyncRestTemplate类型的 bean。创建此类 Bean 由您自己决定。然后我们对其进行检测。

要阻止AsyncRestTemplate功能,请将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 Template

有时您需要使用异步实现模板的多个实现。在以下代码段中,您可以看到有关如何设置自定义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;
	}

}

64.6.3 WebClient

我们注入了一个ExchangeFilterFunction实现,该实现创建了一个范围,并通过成功时和错误时回调来处理关闭 Client 端范围。

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

Tip

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

64.6.4 Traverson

如果您使用Traverson库,则可以将RestTemplate作为 bean 注入 Traverson 对象。由于RestTemplate已被拦截,因此您将获得对 Client 端中跟踪的全面支持。以下伪代码显示了如何执行此操作:

@Autowired RestTemplate restTemplate;

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

64.6.5 Apache HttpClientBuilder 和 HttpAsyncClientBuilder

我们对HttpClientBuilderHttpAsyncClientBuilder进行检测,以便将跟踪上下文注入到已发送的请求中。

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

64.6.6 Netty HttpClient

我们检测 Netty 的HttpClient

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

Tip

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

64.6.7 UserInfoRestTemplateCustomizer

我们检测 Spring Security 的UserInfoRestTemplateCustomizer

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

64.7 Feign

默认情况下,Spring Cloud Sleuth 通过TraceFeignClientAutoConfiguration与 Feign 集成。您可以通过将spring.sleuth.feign.enabled设置为false来完全禁用它。如果这样做,则不会进行与 Feign 相关的检测。

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

64.8 gRPC

Spring Cloud Sleuth 为gRPCTraceGrpcAutoConfiguration提供了工具。您可以通过将spring.sleuth.grpc.enabled设置为false来完全禁用它。

64.8.1 Dependencies

Tip

gRPC 集成依赖于两个外部库来检测 Client 端和服务器,并且这两个库都必须在 Classpath 上才能启用检测。

Maven:

<dependency>
			<groupId>io.github.lognet</groupId>
			<artifactId>grpc-spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>io.zipkin.brave</groupId>
			<artifactId>brave-instrumentation-grpc</artifactId>
		</dependency>

Gradle:

compile("io.github.lognet:grpc-spring-boot-starter")
    compile("io.zipkin.brave:brave-instrumentation-grpc")

64.8.2 服务器检测

Spring Cloud Sleuth 利用 grpc-spring-boot-starter 向带有@GRpcServiceComments 的所有服务注册 Brave 的 gRPC 服务器拦截器。

64.8.3Client 端检测

gRPCClient 端利用ManagedChannelBuilder构造用于与 gRPC 服务器通信的ManagedChannel。本地ManagedChannelBuilder提供静态方法作为构建ManagedChannel实例的入口点,但是,此机制不受 Spring 应用程序上下文的影响。

Tip

Spring Cloud Sleuth 提供了一个SpringAwareManagedChannelBuilder,可以通过 Spring 应用程序上下文对其进行自定义并由 gRPCClient 端注入。 创建ManagedChannel实例时必须使用此构建器.

Sleuth 创建一个TracingManagedChannelBuilderCustomizer,将 Brave 的 Client 端拦截器注入SpringAwareManagedChannelBuilder

64.9 异步通信

64.9.1 @AsyncComments 方法

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

如果您使用@AsyncComments 方法,我们将自动创建具有以下 Feature 的新 Span:

  • 如果该方法以@SpanNameComments,则 Comments 的值是 Span 的名称。

  • 如果该方法未使用@SpanNameComments,则 Span 名称为 Comments 的方法名称。

  • 该范围用方法的类名和方法名标记。

64.9.2 @计划的带 Comments 的方法

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

如果您使用@ScheduledComments 方法,我们将自动创建具有以下 Feature 的新 Span:

  • Span 名称是带 Comments 的方法名称。

  • 该范围用方法的类名和方法名标记。

如果要跳过某些带有@ScheduledComments 的类的 Span 创建,则可以使用与@ScheduledComments 的类的完全限定名称匹配的正则表达式设置spring.sleuth.scheduled.skipPattern。如果同时使用spring-cloud-sleuth-streamspring-cloud-netflix-hystrix-stream,则会为每个 HystrixMetrics 创建一个范围,并将其发送到 Zipkin。这种行为可能很烦人。这就是默认情况下spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask的原因。

64.9.3 Executor,ExecutorService 和 ScheduledExecutorService

我们提供LazyTraceExecutorTraceableExecutorServiceTraceableScheduledExecutorService。每次提交,调用或计划新任务时,这些实现都会创建 Span。

以下示例显示了使用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"));

Tip

Sleuth 不适用于parallelStream()。如果要使跟踪信息在流中传播,则必须使用supplyAsync(…)的方法,如前所示。

如果有实现您想从 Span 创建中排除的Executor接口的 bean,则可以使用spring.sleuth.async.ignored-beans属性,在其中可以提供 bean 名称的列表。

Actuator 的自定义

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

@Configuration
@EnableAutoConfiguration
@EnableAsync
// add the infrastructure role to ensure that the bean gets auto-proxied
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
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);
	}

}

Tip

为确保您的配置得到后期处理,请记住在@Configuration类上添加@Role(BeanDefinition.ROLE_INFRASTRUCTURE)

64.10 Messaging

可以通过将spring.sleuth.messaging.enabled属性设置为false来禁用此部分的功能。

64.10.1 Spring Integration 和 Spring Cloud Stream

Spring Cloud Sleuth 与Spring Integration集成。它为发布和订阅事件创建 Span。要禁用 Spring Integration 工具,请将spring.sleuth.integration.enabled设置为false

您可以提供spring.sleuth.integration.patterns模式,以明确提供要包括在跟踪中的通道的名称。默认情况下,除hystrixStreamOutputChannels 外的所有 Channels 都包括在内。

Tip

使用Executor构建 Spring Integration IntegrationFlow时,必须使用Executor的未跟踪版本。用TraceableExecutorService装饰 Spring Integration Executor 通道会导致 Span 未正确关闭。

如果要定制从消息头读取和写入跟踪上下文的方式,则足以注册类型的 bean:

  • Propagation.Setter<MessageHeaderAccessor, String>-用于将 Headers 写入邮件

  • Propagation.Getter<MessageHeaderAccessor, String>-用于从邮件中读取标题

64.10.2 Spring RabbitMq

我们对RabbitTemplate进行检测,以便将跟踪 Headers 注入到消息中。

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

64.10.3SpringKafka

我们对 Spring Kafka 的ProducerFactoryConsumerFactory进行检测,以便将跟踪 Headers 注入到创建的 Spring Kafka 的ProducerConsumer中。

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

64.10.4 Spring JMS

我们对JmsTemplate进行检测,以便将跟踪 Headers 注入到消息中。我们还在 Consumer 方面支持@JmsListener个带 Comments 的方法。

要阻止此功能,请将spring.sleuth.messaging.jms.enabled设置为false

Tip

我们不支持 JMS 的 Baggage 运送

64.11 Zuul

我们通过使用跟踪信息丰富功能区请求来检测 Zuul 功能区集成。要禁用 Zuul 支持,请将spring.sleuth.zuul.enabled属性设置为false