背景
之前写过一篇 从 Dapper 到 OpenTelemetry:分布式追踪的演进之旅的文章,主要是从概念上讲解了 Trace 在 OpenTelemetry 的中的场景和使用。
也写过一篇 实操 OpenTelemetry:通过 Demo 掌握微服务监控的艺术:如何从一个 demo 开始集成 OpenTelemetry。
但还是有不少小伙伴反馈说无法快速上手(可能也是这个 demo 的项目比较多),于是我准备从 0 开始从真实的代码一步步带大家集成 OpenTelemetry
,因为 OpenTelemetry 本身是跨多种语言的,所以也会以两种语言为(Java、Golang)主进行讲解。
使用这两种语言主要是因为 Java 几乎全是自动埋点,而 Golang 因为语言特性,大部分都得硬编码埋点;覆盖到这两种场景后其他语言也是类似的,顶多只是 API 名称有些许区别。
在这个过程中也会穿插一些 OpenTelemetry 的原理,希望整个过程下来大家可以在项目中实际运用起来,同时也能知其所以然。
项目结构
在这个过程中会涉及到以下项目:
名称 | 作用 | 语言 | 版本 |
---|---|---|---|
java-demo | 发送 gRPC 请求的客户端 | Java | opentelemetry-agent: 2.4.0/SpringBoot: 2.7.14 |
k8s-combat | 提供 gRPC 服务的服务端 | Golang | go.opentelemetry.io/otel: 1.28/ Go: 1.22 |
Jaeger | trace 存储的服务端以及 TraceUI 展示 | Golang | jaegertracing/all-in-one:1.56 |
opentelemetry-collector-contrib | OpenTelemetry 的 collector 服务端,用于收集 trace/metrics/logs 然后写入到远端存储 | Golang | otel/opentelemetry-collector-contrib:0.98.0 |

在开始之前我们先看看实际的效果,我们需要先把 collector 和 Jaeger 部署好:
docker run --rm -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 14250:14250 \
-p 14268:14268 \
-p 14269:14269 \
-p 9411:9411 \
jaegertracing/all-in-one:1.56
docker run --rm -d -v $(pwd)/coll-config.yaml:/etc/otelcol-contrib/config.yaml --name coll \
-p 5318:4318 \
-p 5317:4317 \
otel/opentelemetry-collector-contrib:0.98.0
这里有一个 coll-config
的配置文件如下:
receivers:
otlp:
protocols:
grpc:
http:
exporters:
debug:
otlp:
endpoint: "127.0.0.1:4317"
tls:
insecure: true
processors:
batch:
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp, debug]
重点是这里的 endpoint: "127.0.0.1:4317"
我们需要配置位 Jaeger 的 IP 和端口。
更多关于这里的配置会在后续单独的 collector 章节中讲解。
这两个服务都启动成功后再启动我们的 Java 客户端和 Go 服务端:
java -javaagent:opentelemetry-javaagent-2.4.0-SNAPSHOT.jar \
-Dotel.traces.exporter=otlp \
-Dotel.metrics.exporter=otlp \
-Dotel.logs.exporter=none \
-Dotel.service.name=demo \
-Dotel.exporter.otlp.protocol=grpc \
-Dotel.propagators=tracecontext,baggage \
-Dotel.exporter.otlp.endpoint=http://127.0.0.1:5317 \
-jar target/demo-0.0.1-SNAPSHOT.jar
# Golang
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:5317
export OTEL_RESOURCE_ATTRIBUTES=service.name=k8s-combat
./k8s-combat
可以看到不管是 Java 还是 Golang 应用都是需要配置 OTEL_EXPORTER_OTLP_ENDPOINT
参数,也就是 opentelemetry-collector-contrib
的地址。
其余的一些配置在后面会讲到。
curl http://127.0.0.1:9191/request\?name\=1232
然后我们触发一下 Java 客户端的入口,就可以在 JaegerUI 中查询到刚才的链路了。http://localhost:16686/search