62. 整合
62.1 OpenTracing
Spring Cloud Sleuth 与OpenTracing兼容。如果在 classpath 上有 OpenTracing,我们会自动注册 OpenTracing Tracer
bean。如果要禁用此功能,请将spring.sleuth.opentracing.enabled
设置为false
62.2 Runnable 和 Callable
如果将逻辑包装在Runnable
或Callable
中,则可以将这些 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 支持
如果你的控制器返回Callable
或WebAsyncTask
,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
我们检测HttpClientBuilder
和HttpAsyncClientBuilder
,以便跟踪 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-stream
和spring-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
我们提供LazyTraceExecutor
,TraceableExecutorService
和TraceableScheduledExecutorService
。这些 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 IntegrationIntegrationFlow
时,必须使用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 的ProducerFactory
和ConsumerFactory
,以便跟踪 headers 被注入到创建的 Spring Kafka 的Producer
和Consumer
中。
要阻止此 feature,请将spring.sleuth.messaging.kafka.enabled
设置为false
。
我们不支持通过
@KafkaListener
annotation 传播 context。检查此问题了解更多信息。
62.10 Zuul
我们通过使用跟踪信息丰富 Ribbon 请求来检测 Zuul Ribbon integration。要禁用 Zuul 支持,请将spring.sleuth.zuul.enabled
property 设置为false
。