15. 集成
15.1. OpenTracing
Spring Cloud Sleuth 与 OpenTracing 兼容。
如果您在 Classpath 上有 OpenTracing,我们会自动注册 OpenTracingTracer
豆。
如果要禁用此功能,请将spring.sleuth.opentracing.enabled
自false
15.2. Runnable 和 Callable
如果你将你的逻辑包装在Runnable
或Callable
中,您可以将这些类包装在其 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。
15.3. Spring Cloud 断路器
如果你在 Classpath 上有 Spring Cloud CircuitBreaker,我们将包装传递的命令Supplier
和回退Function
在其跟踪表示形式中。要禁用此插桩集spring.sleuth.circuitbreaker.enabled
自false
.
15.4. 海斯特里克斯
15.4.1. 自定义并发策略
我们注册了一个自定义HystrixConcurrencyStrategy
叫TraceCallable
那包了所有Callable
实例。
该策略可以启动或继续 span,具体取决于在调用 Hystrix 命令之前是否已经在进行跟踪。
或者,您可以将spring.sleuth.hystrix.strategy.passthrough
自true
如果您不想启动新的 span,只需将跟踪上下文传播到 Hystrix 执行线程。
要禁用自定义 Hystrix 并发策略,请将spring.sleuth.hystrix.strategy.enabled
自false
.
15.4.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();
}
};
15.5. RxJava
我们注册了一个自定义RxJavaSchedulersHook
那包了所有Action0
实例在他们的 Sleuth 代表中,称为TraceAction
.
钩子可以启动或继续 span,具体取决于在调度 Action 之前是否已经在进行跟踪。
要禁用自定义RxJavaSchedulersHook
中,将spring.sleuth.rxjava.schedulers.hook.enabled
自false
.
您可以为不希望为其创建 span 的线程名称定义正则表达式列表。
为此,请在spring.sleuth.rxjava.schedulers.ignoredthreads
财产。
反应式编程和 Sleuth 的建议方法是使用 Reactor 支持。 |
15.6. HTTP 集成
可以通过设置spring.sleuth.web.enabled
值等于false
.
15.6.1. HTTP 过滤器
通过TracingFilter
,则所有采样的传入请求都会导致创建 Span。
该 Span 的名称是http:
+ 请求发送到的路径。
例如,如果请求被发送到/this/that
那么 name 将为http:/this/that
.
您可以通过设置spring.sleuth.web.skipPattern
财产。
如果你有ManagementServerProperties
在 Classpath 上,其值为contextPath
附加到提供的 skip 模式。
如果你想重用 Sleuth 的默认跳过模式并只附加你自己的模式,请使用spring.sleuth.web.additionalSkipPattern
.
默认情况下,所有 Spring Boot Actuator 端点都会自动添加到跳过模式中。
如果要禁用此行为,请将spring.sleuth.web.ignore-auto-configured-skip-patterns
自true
.
要更改跟踪过滤器注册的顺序,请将spring.sleuth.web.filter-order
财产。
要禁用记录未捕获异常的过滤器,您可以禁用spring.sleuth.web.exception-throwing-filter-enabled
财产。
15.6.2. HandlerInterceptor
由于我们希望 span 名称精确,因此我们使用TraceHandlerInterceptor
,或者将现有的HandlerInterceptor
或直接添加到现有HandlerInterceptors
.
这TraceHandlerInterceptor
将特殊请求属性添加到给定的HttpServletRequest
.
如果TracingFilter
看不到此属性,它会创建一个 ”fallback
“ span,这是在服务器端创建的附加 span,以便在 UI 中正确显示跟踪。
如果发生这种情况,则可能缺少 instrumentation。
在这种情况下,请在 Spring Cloud Sleuth 中提交问题。
15.6.3. 异步 Servlet 支持
如果您的控制器返回Callable
或WebAsyncTask
,Spring Cloud Sleuth 会继续现有 span,而不是创建一个新的 span。
15.6.4. WebFlux 支持
通过TraceWebFilter
,则所有采样的传入请求都会导致创建 Span。
该 Span 的名称是http:
+ 请求发送到的路径。
例如,如果请求被发送到/this/that
,则名称为http:/this/that
.
您可以使用spring.sleuth.web.skipPattern
财产。
如果你有ManagementServerProperties
在 Classpath 上,其值为contextPath
附加到提供的 skip 模式。
如果你想重用 Sleuth 的默认跳过模式并附加你自己的 Skip,请使用spring.sleuth.web.additionalSkipPattern
.
要更改跟踪过滤器注册的顺序,请将spring.sleuth.web.filter-order
财产。
15.6.5. Dubbo RPC 支持
通过与 Brave 的集成,Spring Cloud Sleuth 支持 Dubbo。
只需添加brave-instrumentation-dubbo
Dependency:
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-dubbo</artifactId>
</dependency>
您还需要设置dubbo.properties
文件,其中包含以下内容:
dubbo.provider.filter=tracing
dubbo.consumer.filter=tracing
15.7. HTTP 客户端集成
15.7.1. 同步 REST 模板
我们注入一个RestTemplate
interceptor 来确保所有跟踪信息都传递给请求。
每次进行调用时,都会创建一个新的 Span。
收到响应后,它将关闭。
要阻止同步RestTemplate
功能, 集spring.sleuth.web.client.enabled
自false
.
您必须注册RestTemplate 作为 bean,以便注入拦截器。
如果您创建一个RestTemplate 实例具有new 关键字,则插桩不起作用。 |
15.7.2. 异步 REST 模板
从 Sleuth 开始2.0.0 ,我们不再注册AsyncRestTemplate 类型。
创建这样的 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 模板
有时,您需要使用 Asynchronous 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;
}
}
15.7.3.WebClient
我们注入一个ExchangeFilterFunction
创建 Span 并通过 on-success 和 on-error 回调来关闭客户端 Span。
要阻止此功能,请将spring.sleuth.web.client.enabled
自false
.
您必须注册WebClient 或WebClient.Builder 作为 Bean,以便应用跟踪插桩。
如果您手动创建一个WebClient 或WebClient.Builder ,则检测不起作用。 |
15.7.4. 遍历
如果您使用 Traverson 库,则可以注入RestTemplate
作为 bean 放入 Traverson 对象中。
因为RestTemplate
已被拦截,则您可以在客户端中获得对跟踪的全面支持。以下伪代码
演示如何执行此作:
@Autowired RestTemplate restTemplate;
Traverson traverson = new Traverson(URI.create("https://some/address"),
MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate);
// use Traverson
15.7.5. 阿帕奇HttpClientBuilder
和HttpAsyncClientBuilder
我们检测HttpClientBuilder
和HttpAsyncClientBuilder
因此
跟踪上下文被注入到发送的请求中。
要阻止这些功能,请将spring.sleuth.web.client.enabled
自false
.
15.7.6. NettyHttpClient
我们检测 Netty 的HttpClient
.
要阻止此功能,请将spring.sleuth.web.client.enabled
自false
.
您必须注册HttpClient 作为 Bean 进行,以便进行检测。
如果您创建一个HttpClient 实例具有new 关键字,则插桩不起作用。 |
15.7.7.UserInfoRestTemplateCustomizer
我们检测 Spring Security 的UserInfoRestTemplateCustomizer
.
要阻止此功能,请将spring.sleuth.web.client.enabled
自false
.
15.8. 假动作
默认情况下,Spring Cloud Sleuth 通过以下方式提供与 Feign 的集成TraceFeignClientAutoConfiguration
.
您可以通过设置spring.sleuth.feign.enabled
自false
.
如果这样做,则不会发生与 Feign 相关的插桩。
Feign 插桩的一部分是通过FeignBeanPostProcessor
.
您可以通过设置spring.sleuth.feign.processor.enabled
自false
.
如果将其设置为false
,Spring Cloud Sleuth 不会检测任何自定义 Feign 组件。
但是,所有默认插桩仍然存在。
15.9. gRPC
Spring Cloud Sleuth 通过以下方式为 gRPC 提供检测TraceGrpcAutoConfiguration
.您可以通过设置spring.sleuth.grpc.enabled
自false
.
15.9.1. 变体 1
依赖
gRPC 集成依赖于两个外部库来检测客户端和服务器,并且这两个库都必须位于类路径上才能启用检测。 |
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")
服务器检测
Spring Cloud Sleuth 利用 grpc-spring-boot-starter 向所有带有 Comments 的服务注册 Brave 的 gRPC 服务器拦截器@GRpcService
.
客户端检测
gRPC 客户端利用ManagedChannelBuilder
构造一个ManagedChannel
用于与 gRPC 服务器通信。原生ManagedChannelBuilder
提供静态方法作为构造ManagedChannel
实例,但是,此机制不受 Spring 应用程序上下文的影响。
Spring Cloud Sleuth 提供了一个SpringAwareManagedChannelBuilder 可以通过 Spring 应用程序上下文进行自定义,并由 gRPC 客户端注入。创建ManagedChannel 实例。
|
Sleuth 会创建一个TracingManagedChannelBuilderCustomizer
它将 Brave 的客户端拦截器注入SpringAwareManagedChannelBuilder
.
15.9.2. 变体 2
Grpc Spring Boot Starter 会自动检测是否存在 Spring Cloud Sleuth 和 brave 的 gRPC 检测,并注册必要的客户端和/或服务器工具。
15.10. 异步通信
15.10.1.@Async
带注释的方法
在 Spring Cloud Sleuth 中,我们检测与异步相关的组件,以便在线程之间传递跟踪信息。
您可以通过设置spring.sleuth.async.enabled
自false
.
如果你用@Async
,我们会自动修改现有的 Span,如下所示:
-
如果方法带有
@SpanName
,则注释的值是 Span 的名称。 -
如果方法没有使用
@SpanName
中,Span name 是带注释的方法名称。 -
span 使用方法的类名和方法名进行标记。
由于我们正在修改现有 span,如果您想保持其原始名称(例如,通过接收 HTTP 请求创建的 span)
您应该将@Async
带有@NewSpan
注释或手动创建新 Span。
15.10.2.@Scheduled
带注释的方法
在 Spring Cloud Sleuth 中,我们检测计划的方法执行,以便在线程之间传递跟踪信息。
您可以通过设置spring.sleuth.scheduled.enabled
自false
.
如果你用@Scheduled
,我们会自动创建一个具有以下特征的新 Span:
-
span name 是带注释的方法名称。
-
span 使用方法的类名和方法名进行标记。
如果您想为某些@Scheduled
注解类,您可以设置spring.sleuth.scheduled.skipPattern
替换为与@Scheduled
annotated 类。
如果您使用spring-cloud-sleuth-stream
和spring-cloud-netflix-hystrix-stream
一起为每个 Hystrix 指标创建一个 span 并发送到 Zipkin。
此行为可能很烦人。这就是为什么默认情况下,spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask
.
15.10.3. Executor、ExecutorService 和 ScheduledExecutorService
我们提供LazyTraceExecutor
,TraceableExecutorService
和TraceableScheduledExecutorService
.这些实施在每次提交、调用或计划新任务时都会创建 span。
以下示例显示了如何使用TraceableExecutorService
使用CompletableFuture
:
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(...) ,如前所述。 |
如果存在实现Executor
您想要的界面
要从 SPAN 创建中排除,您可以使用spring.sleuth.async.ignored-beans
属性,您可以在其中提供 Bean 名称列表。
Executor 的自定义
有时,您需要设置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);
}
}
要确保您的配置得到后处理,请记住
要添加@Role(BeanDefinition.ROLE_INFRASTRUCTURE) 在您的@Configuration 类 |
15.11. 消息传递
可以通过设置spring.sleuth.messaging.enabled
值等于false
.
15.11.1. Spring 集成和 Spring Cloud Stream
Spring Cloud Sleuth 与 Spring 集成。
它为 publish 和 subscribe 事件创建 span。
要禁用 Spring 集成插桩,请将spring.sleuth.integration.enabled
自false
.
您可以提供spring.sleuth.integration.patterns
pattern 显式提供要包含以进行跟踪的通道的名称。
默认情况下,除hystrixStreamOutput
频道。
使用Executor 构建 Spring 集成IntegrationFlow ,则必须使用Executor .
用 Spring Integration Executor Channel 装饰TraceableExecutorService 导致 Span 闭合不当。 |
如果要自定义从消息标头读取和写入跟踪上下文的方式, 注册 Bean 类型就足够了:
-
Propagation.Setter<MessageHeaderAccessor, String>
- 用于将标头写入消息 -
Propagation.Getter<MessageHeaderAccessor, String>
- 用于从消息中读取标头
15.11.2. Spring RabbitMq
我们检测RabbitTemplate
以便注入跟踪标头
放入消息中。
要阻止此功能,请将spring.sleuth.messaging.rabbit.enabled
自false
.
15.11.3. Spring Kafka
我们为 Spring Kafka 的ProducerFactory
和ConsumerFactory
以便将跟踪标头注入到创建的 Spring Kafka 的Producer
和Consumer
.
要阻止此功能,请将spring.sleuth.messaging.kafka.enabled
自false
.
15.11.4. Spring Kafka 流
我们检测KafkaStreams
KafkaClientSupplier
以便跟踪标头
注入到Producer
和Consumer`s. A `KafkaStreamsTracing
豆
允许通过额外的TransformerSupplier
和ProcessorSupplier
方法。
要阻止此功能,请将spring.sleuth.messaging.kafka.streams.enabled
自false
.
15.11.5. Spring JMS
我们检测JmsTemplate
以便注入跟踪标头
放入消息中。我们还支持@JmsListener
在消费者端的 annotated 方法。
要阻止此功能,请将spring.sleuth.messaging.jms.enabled
自false
.
我们不支持 JMS 的行李传播 |
15.11.6. Spring Cloud AWS 消息收发 SQS
我们仪器@SqsListener
它由org.springframework.cloud:spring-cloud-aws-messaging
以便从消息中提取跟踪标头,并将跟踪放入上下文中。
要阻止此功能,请将spring.sleuth.messaging.sqs.enabled
自false
.
15.12. 祖尔
我们通过使用跟踪信息丰富 Ribbon 请求来检测 Zuul Ribbon 集成。
要禁用 Zuul 支持,请将spring.sleuth.zuul.enabled
property 设置为false
.
15.13. Redis
我们设置tracing
property 添加到 LettcueClientResources
实例以启用在 Lettuce 中构建的 Brave 跟踪。
要禁用 Redis 支持,请将spring.sleuth.redis.enabled
property 设置为false
.
15.14. Quartz
我们通过向 Quartz Scheduler 添加 Job/Trigger 侦听器来检测 quartz 作业。
要关闭此功能,请将spring.sleuth.quartz.enabled
property 设置为false
.
15.15. Project Reactor (项目 Reactor)
15.15.1. 来自 Spring Cloud Sleuth 2.2.8(含)
使用新的 Reactor 队列包装机制 (Reactor 3.3.14),我们正在检测 Reactor 切换线程的方式。您应该观察到性能的显著改进。要启用此功能,您必须设置spring.sleuth.reactor.decorate-queues
选项设置为true
.
15.15.2. 到 Spring Cloud Sleuth 2.2.8(独占)
对于依赖于 Project Reactor 的项目,例如 Spring Cloud Gateway,我们建议将spring.sleuth.reactor.decorate-on-each
选项设置为false
.这样,与标准插桩机制相比,应该观察到性能提升的增加。这个选项的作用是包装装饰onLast
运算符而不是onEach
这将导致创建的对象要少得多。这样做的缺点是,当 Project Reactor 更改线程时,跟踪传播将继续而不会出现问题,但是任何依赖于ThreadLocal
例如 MDC 条目可能有问题。