Spring Cloud项目接入Jaeger
简介
随着分布式系统中调用关系的复杂化加大,调用链系统越来越迫切需要了,在Spring Cloud 以及 Google Dapper 论文发表之后,来了很多调用链中间价,如: skywalking 等,今天我分享下jaeger项目,jaeger是 cncf机构(Cloud Native Computing Foundation,www.cncf.io/)孵化出来的,以后业类…
jaeger 服务端安装
官网: www.jaegertracing.io/docs/1.16/g…
我是windows环境,所以演示windows环境,其他环境大体类似。下载,解压:

新建 jaeger.bat 文件,内容为: jaeger-all-in-one ,每次启动双击 jaeger.bat 即可,浏览器打开后台地址,http://localhost:16686/search
本地代码
pom.xml 文件引入:
<opentracing-okhttp3.version>2.0.1</opentracing-okhttp3.version>
<opentracing-spring-jaeger-cloud-starter.version>2.0.0</opentracing-spring-jaeger-cloud-starter.version>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>
<version>${opentracing-spring-jaeger-cloud-starter.version}</version>
<exclusions>
<!--调用链监控无法支持TDDL,用到TDDL的应用,需把jdbc监控排除掉,否则会报错:Caused by: java.lang.IllegalArgumentException: Invalid JDBC URL. Expected to find the database type after the first ':'. URL: null-->
<exclusion>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-cloud-jdbc-starter</artifactId>
</exclusion>
<exclusion>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-cloud-mongo-starter</artifactId>
</exclusion>
<exclusion>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-cloud-reactor-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--RpcHandler 使用了 OkHttp-->
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-okhttp3</artifactId>
<version>${opentracing-okhttp3.version}</version>
</dependency>
其中, opentracing-spring-cloud-starter 官方包含:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-core</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-web-starter</artifactId>
<version>${version.io.opentracing.contrib-opentracing-spring-web}</version>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-messaging-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-rabbitmq-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-jdbc-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-jms-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-feign-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-hystrix-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-rxjava-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-mongo-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-websocket-starter</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opentracing-spring-cloud-zuul-starter</artifactId>
</dependency>
引入:opentracing-spring-jaeger-cloud-starter 依赖,他就引入了一系列和Spring Cloud组件其他的依赖了。同时因为我用到了ok-http,所以加上了 opentracing-okhttp3 依赖。

主代码例子:
不需要任何代码,只需yml配置如下:
opentracing:
jaeger:
enabled: true # 是否启用 jaeger
udpSender: # 使用udp发送
host: 127.0.0.1
port: 6831
max-packet-size: 65000
probabilisticSampler: #采样率配置
samplingRate: 1.0
enable-b3-propagation: true
expandExceptionLogs: true
log-spans: false # 是否打印日志的span信息,不用打印
测试图:

具体代码: gitee.com/xiaomaoguai…
源码扩展
默认tracing组件,看起来实现没有像skywalking那样通过agent的方式的轻便以及对应用的无侵入性。当然jaeger也提供了类似agent方式来搜集跨度信息的,只不过jaeger目前支持的组件还比较少,因此很多情况需要自己来扩展插件了。所以简单看下jaeger源码:
首先根据配置,找到jaeger代码入口: JaegerAutoConfiguration ,可以看到所有的配置都在: JaegerConfigurationProperties 里面了。
@Configuration
@ConditionalOnClass(io.jaegertracing.internal.JaegerTracer.class)
@ConditionalOnMissingBean(io.opentracing.Tracer.class)
@ConditionalOnProperty(value = "opentracing.jaeger.enabled", havingValue = "true", matchIfMissing = true)
@AutoConfigureBefore(io.opentracing.contrib.spring.tracer.configuration.TracerAutoConfiguration.class)
@EnableConfigurationProperties(JaegerConfigurationProperties.class)
public class JaegerAutoConfiguration {
@Autowired(required = false)
private List<TracerBuilderCustomizer> tracerCustomizers = Collections.emptyList();
@Bean
public io.opentracing.Tracer tracer(Sampler sampler,
Reporter reporter,
Metrics metrics,
JaegerConfigurationProperties properties) {
final JaegerTracer.Builder builder =
new JaegerTracer.Builder(properties.getServiceName())
.withReporter(reporter)
.withSampler(sampler)
.withTags(properties.determineTags())
.withMetrics(metrics);
tracerCustomizers.forEach(c -> c.customize(builder));
return builder.build();
}
日志显示trace 和 span
需要配置 自定义 TracerBuilderCustomizer ,可以参见代码, WrappedThreadLocalScopeManager
搜集的日志信息是没有对关键字进行脱敏的
可以暴露接口出来,搜集信息的时候对搜集信息进行脱敏处理。
jaeger动态启用禁用等
jaeger虽然提供了 采样率,但是我们第一次集成jaeger时,可能在某些情况需要禁用jaeger,暴露开关标识给到外面,在自定义搜集入口判断开关,减少采样率。