如果还不熟悉 Tracing 的基本概念,可以先翻看前面一篇文章《Java 服务接入 OpenTracing(1)--从 Tracing 到 OpenTracing》。前文我们已经提到,OpenTracing API 只定义 Span 采集/上报过程的相关接口,而具体的采集实现/上报实现/聚合查询实现都是由具体的 Tracing 项目选择支持实现。所以本文以 Jaeger 为例子来描述如何让 Java 项目快速接入 Tracing 功能。
接入前准备
搭建 Collector 和 Querier
Jaeger 提供了一个 all-in-one 的镜像,非常方便于在开发环境使用,只要有 docker 环境,一行代码就可以运行起来。
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:1.21
这个应用里面同时包含了 Collector 和 Querier 的功能。从 Jaeger 官方架构图的角度来开,这个 all-in-one 还包含了 jaeger-agent 功能。但是这个镜像虽然功能很全面,但是不适合在生产环境使用。一是因为这个镜像起来的服务,数据是存在内存的,无法持久化 trace 信息。二是在生产环境数据量是比较大的,在 Reporter 端到 Collector 端的数据传输还需要考虑流量的问题。所以如果是上生产环境,建议参考官方提供的机构,再根据实际情况做一些功能增减。
执行上述指令后系统下载包,并启动服务。执行 docker ps | grep jaeger, 在 status 列看到 up xxx 说明启动成功
╰$ docker ps | grep jaeger
a4848198fca0 jaegertracing/all-in-one:1.21 "/go/bin/all-in-one-…" 2 minutes ago Up 2 minutes 0.0.0.0:5775->5775/udp, 0.0.0.0:5778->5778/tcp, 0.0.0.0:9411->9411/tcp, 0.0.0.0:14250->14250/tcp, 0.0.0.0:14268->14268/tcp, 0.0.0.0:6831-6832->6831-6832/udp, 0.0.0.0:16686->16686/tcp jaeger
这个时候,就可以通过 http://localhost:16686 访问 jaeger ui 了。但是此时,因为没有任务服务接入,所以 Service 还没有可选项目。
准备被织入 java 项目(如果已经有自己的项目jar包,可以直接跳过此步)
我们这里使用的是其官网提供的 demo 的 java 项目
项目地址: [opentracing-contrib/java-specialagent-demo]
git clone 项目,然后构建出演示 app 的 jar 包 (需要安装和配置好 git 和 maven3+ )
git clone https://github.com/opentracing-contrib/java-specialagent-demo
cd microdonuts
mvn package
# maven 执行日志...
等待 maven 执行完成后,会生成一个 target/ 文件夹,里面会有一个 api-1.0-SNAPSHOT.jar 文件,这个 jar 就是我们要织入的目标项目
准备 java-specialagent 包
java-specialagent 是 OpenTracing 里面对 java 使用 javaagent 方式织入代码实现接入的开源项目,由于其接入没有代码入侵性,一次接入可以实现多开源项目的 Traicng 采点,因此成了最常用的 Instrument 项目。
项目地址: [opentracing-contrib/java-specialagent]
使用如下指令下载稳定包版本 1.7.4 到启动目录
# 在 java-specialagent-demo/microdonuts 目录下面执行
wget -O opentracing-specialagent-1.7.4.jar "https://repo1.maven.org/maven2/io/opentracing/contrib/specialagent/opentracing-specialagent/1.7.4/opentracing-specialagent-1.7.4.jar"
Java 项目织入 specialagent
java 项目织入 specialagent 非常简单只需要在 java 启动指令里面增加 javaagent 以及 Tracing 的一些启动参数。如下
# 在 java-specialagent-demo/microdonuts 目录下面执
java -cp ./target/api-1.0-SNAPSHOT.jar -javaagent:./opentracing-specialagent-1.7.4.jar -Dsa.exporter=jaeger -Dsa.log.level=FINE -DJAEGER_SERVICE_NAME=apiDemo -DJAEGER_SAMPLER_TYPE=probabilistic -DJAEGER_SAMPLER_PARAM=1 -DJAEGER_ENDPOINT="http://localhost:14268/api/traces" com.otsample.api.App
里面有一个参数 -javaagent:。SpecialAgent 就是利用 java 1.5+ 支持的 javaagent 功能来实现非侵入式织入的。
另外还有不少的 -Dxxx 参数。这些参数 java 本身不使用,而是当作环境变量传给 SpeicalAgent 使用的。这些参数都可以在 SpecialAgent 的 Github 的 README 文件中找到。下面列举下上文使用参数
- sa.exporter: SpecialAgent 的 Tracer 选择参数,目前可选的 Tracer 有 jaeger, lightstep, wavefront, otel, or mock. 因为我们 Collector 和 Querier 用的是 jaeger 的。为了保持兼容性,则设置了 jaeger。根据我们选择了 jaeger 作为 Tracer, 则对应需要设置 Jaeger Tracer 的参数。 参考:Jaeger Configuration Envs
- JAEGER_SERVICE_NAME: 指定当前的服务名,对应的就是 jaeger-query ui 的 services
- JAEGER_SAMPLER_TYPE: 指定采样方法。一般我们使用百分比采样(probabilistic)。
- JAEGER_SAMPLER_PARAM:指定采样参数,如果采样方法选择了百分比,则这个参数就是具体百分比的值。该参数取值为 0.0-1.0。我们设置为1代表全采样。
- JAEGER_ENDPOINT: 值采集 Span 后的上报地址。如果选择了这个参数,则是直接通过 http 方式上报到 Collector。这种方式我们一般只在开发环境调试使用。如果是生产环境则推荐使用官方的架构方式,使用
JAEGER_AGENT_HOST和JAEGER_AGENT_PORT参数,以 UDP 格式上报给 jaeger-agent。然后再统一由 jaeger-agent 根据一些全局设置做处理,转换格式,再批量上报给 Collector。
- sa.integration.*.disable=true: 默认情况下,所有 instrument rule 都会开启。但是可能有些 instrument rule 不需要用到。所以可以先把这个参数设置为 true。然后在根据需要开启。
- sa.integration.servlet.enable=true: 配合
sa.integration.*.disable=true开启 servlet rule。这样就可以看 Trace 在 servlet 产生了 Span。(其实是在 Filter Chain 最前面塞了个 TraceFilter 进行打点的)。所有可配置的规则在 SpecialAgent 有个表格可以查到,可根据应用的实际情况进行配置。 - sa.log.level: SpecialAgent 的日志级别,默认是 WARING,所以很多织入信息都不会打印。这里调整为 FINE 则可以在启动的时候看到织入的内容有哪一些。如果是生产环境,还是建议设置为 WARNING
启动的时候可以看到许多的织入日志,如果没有错误,说明织入成功。如果报错可能是 rule 所支持的版本不匹配导致的。这个时候则可以更改参数禁用掉有问题的 rule 再启动。
如下是成功的情况
╰$ java -cp ./target/api-1.0-SNAPSHOT.jar -javaagent:./opentracing-specialagent-1.7.4.jar -Dsa.exporter=jaeger -Dsa.log.level=FINE -DJAEGER_SERVICE_NAME=apiDemo -DJAEGER_SAMPLER_TYPE=probabilistic -DJAEGER_SAMPLER_PARAM=1 -DJAEGER_ENDPOINT="http://localhost:14268/api/traces" com.otsample.api.App
Initializing SpecialAgent
<<<<<<<<<<<<<<<<<<<<< Loading AgentRule(s) >>>>>>>>>>>>>>>>>>>>
Installing rule: io.opentracing.contrib.specialagent.rule.asynchttpclient.AsyncHttpClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.httpurlconnection.HttpURLConnectionAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.redisson.RedissonAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.rxjava3.RxJava3AgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.okhttp.OkHttpAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.camel.CamelAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.grizzly.http.server.HttpServerFilterRule
Installing rule: io.opentracing.contrib.specialagent.rule.mongo.driver.MongoDriverAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.jms.JmsAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.jaxrs.JaxRsAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.grpc.GrpcAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.neo4j.driver.Neo4jDriverAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spymemcached.SpymemcachedAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.jms.SpringJmsMQAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.servlet.ServletContextAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.servlet.FilterAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.rabbitmq.client.RabbitMQAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.jedis.JedisAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.pulsar.functions.PulsarFunctionsAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.reactor.MonoAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.reactor.FluxAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.reactor.ParallelFluxAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.cxf.CxfRsClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.cxf.CxfRsServerAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.cxf.CxfWsClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.cxf.CxfWsServerAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.scheduling.SpringSchedulingAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.scheduling.SpringAsyncAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.messaging.SpringMessagingAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.webmvc.SpringWebMvcAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.webmvc.SpringWebRegistryAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.rxjava2.RxJava2AgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.mule4.module.artifact.FilteringArtifactClassLoaderRule
Installing rule: io.opentracing.contrib.specialagent.rule.mule4.module.artifact.FineGrainedControlClassLoaderRule
Installing rule: io.opentracing.contrib.specialagent.rule.concurrent.ExecutorAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.concurrent.FixedDelayAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.concurrent.FixedRateAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.concurrent.ScheduledCallableAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.concurrent.ScheduledRunnableAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.zuul.ZuulAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.netty.NettyAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.playws.PlayWSAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.kafka.SpringKafkaAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.feign.FeignAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.grizzly.http.client.AsyncHttpClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.aws.sdk2.Aws2AgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.dynamic.DynamicAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.akka.actor.AkkaAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.jdbc.JdbcAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.websocket.SpringWebSocketAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.mule4.AbstractProcessorChainRule
Installing rule: io.opentracing.contrib.specialagent.rule.mule4.EventContextRule
Installing rule: io.opentracing.contrib.specialagent.rule.mule4.PrivilegedEventRule
Installing rule: io.opentracing.contrib.specialagent.rule.akka.http.AkkaHttpClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.akka.http.AkkaHttpServerAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.play.PlayAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.elasticsearch.transport.ElasticsearchTransportClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.couchbase.CouchbaseClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.pulsar.client.PulsarClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.googlehttpclient.GoogleHttpClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.kafka.streams.KafkaStreamsAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.dubbo27.DubboAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.thrift.ThriftProtocolAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.thrift.ThriftAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.hazelcast.HazelcastAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.cassandra.driver3.CassandraAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.lettuce.LettuceAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.rabbitmq.SpringRabbitMQAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.kafka.client.KafkaAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.cassandra.driver4.Cassandra4AgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.aws.sdk1.AwsAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.boot.SpringBootAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.apache.httpclient.HttpClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.dubbo26.DubboRpcAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.elasticsearch.rest.ElasticsearchRestClientAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.spring.webflux.SpringWebFluxChainAgentRule
Installing rule: io.opentracing.contrib.specialagent.rule.thread.ThreadAgentRule
<<<<<<<<<<<<<<<<<<<< Loading Trace Exporter >>>>>>>>>>>>>>>>>>>>
Resolving tracer:
jaeger
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Tracer was resolved and registered with GlobalTracer:
io.jaegertracing.internal.JaegerTracer from /var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/iso/jaeger.jar
>>>>>>>>>>>>>>>>>>>> Loaded Trace Exporter <<<<<<<<<<<<<<<<<<<<<
.==============================================================.
| Static Deferred Attach |
| Enabled: true (default) |
|==============================================================|
| To disable Static Deferred Attach, |
| specify -Dsa.init.defer=false |
|=============================================================='
' 0 deferrers were detected, overriding to: -Dsa.init.defer=false
AgentRule.$Access.init(): initializer != null
<<<<<<<<<<<<<<<<< Installing ClassLoaderAgent >>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Installed ClassLoaderAgent <<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<< Installing TracerExclusionAgent >>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Installed TracerExclusionAgent <<<<<<<<<<<<<<<<
Allowing integration with "thread" due to "fingerprint.bin match" for:
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/thread-1.7.4.jar
RuleClassLoader<io.opentracing.contrib.specialagent.RuleClassLoader@6daf2337>.inject(io.opentracing.contrib.specialagent.TracerClassLoader@6f45df59)
Allowing integration with "thrift" due to "fingerprint.bin match" for:
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/opentracing-thrift-0.1.3.jar,
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/thrift-1.7.4.jar
RuleClassLoader<io.opentracing.contrib.specialagent.RuleClassLoader@48c3205a>.inject(io.opentracing.contrib.specialagent.TracerClassLoader@6f45df59)
Allowing integration with "okhttp" due to "fingerprint.bin match" for:
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/opentracing-okhttp3-3.0.0.jar,
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/okhttp-1.7.4.jar
RuleClassLoader<io.opentracing.contrib.specialagent.RuleClassLoader@2679311f>.inject(io.opentracing.contrib.specialagent.TracerClassLoader@6f45df59)
Allowing integration with "thread" due to "fingerprint.bin match" for:
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/thread-1.7.4.jar
Allowing integration with "concurrent" due to "fingerprint.bin match" for:
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/concurrent-1.7.4.jar
>>>>>>>>>>>>>>>>>>>>> Loaded AgentRule(s) <<<<<<<<<<<<<<<<<<<<<
Initialized SpecialAgent in 27.04s
2021-01-26 22:21:39.410:INFO::main: Logging initialized @27605ms to org.eclipse.jetty.util.log.StdErrLog
Allowing integration with "concurrent" due to "fingerprint.bin match" for:
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/concurrent-1.7.4.jar
Allowing integration with "servlet" due to "fingerprint.bin match" for:
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/servlet-1.7.4.jar
Allowing integration with "okhttp" due to "fingerprint.bin match" for:
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/opentracing-okhttp3-3.0.0.jar,
file:/var/folders/qb/xplxl3954wx7md01wvfcgx_m0000gn/T/opentracing-specialagent9180665240455967497/META-INF/plugins/okhttp-1.7.4.jar
2021-01-26 22:21:40.480:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2019-04-18T19:45:35.259Z; git: aa1c656c315c011c01e7b21aabb04066635b9f67; jvm 1.8.0_271-b09
2021-01-26 22:21:40.578:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@787988f4{/,null,AVAILABLE}
2021-01-26 22:21:40.600:INFO:oejsh.ContextHandler:main: Started c.o.a.ApiContextHandler@132e3594{/,null,AVAILABLE}
2021-01-26 22:21:40.600:INFO:oejsh.ContextHandler:main: Started c.o.a.KitchenContextHandler@448462f0{/kitchen,null,AVAILABLE}
2021-01-26 22:21:40.757:INFO:oejs.AbstractConnector:main: Started ServerConnector@2fac80a8{HTTP/1.1,[http/1.1]}{0.0.0.0:10001}
2021-01-26 22:21:40.758:INFO:oejs.Server:main: Started @28952ms
Server@a3b858f{STARTED}[9.4.z-SNAPSHOT] - STARTED
...
...
成功接入 Tracing
启动完毕后,则可以访问应用,这样可以让应用产生 Trace 到 Jaeger Collector 里面。
然后访问 jaeger-query ui 。 就可以看到多了一个叫做 apiDemo 的 service。
点击查询(Find Traces)就可以查到刚才访问应用所产生的许多 traces。这个时候 java 应用就成功接入了 Tracing 功能了
查看 trace 详细
恭喜你,几分钟的功夫,你就成功让你的 Java 应用接入 Tracing 了!
码字不易,欢迎点赞收藏!