Spring Boot应用Docker Compose部署时Jaeger链路追踪失效求助
我帮你一步步梳理可能的原因,大概率是网络连通、环境变量配置或者采样策略的问题,按下面的步骤逐一排查:
1. 确保Jaeger服务和你的应用在同一Docker网络
首先得确认你的docker-compose.yml里已经包含了Jaeger服务,并且和demo应用处于同一个网络(Docker Compose默认会给所有服务创建一个共享网络,但如果手动指定了网络,要确保两者都加入)。
给你个完整的Jaeger服务配置示例,加到你的compose文件里:
version: '2' services: demo: build: . # 后面再加环境变量等配置 jaeger: image: jaegertracing/all-in-one:latest ports: - "16686:16686" # Jaeger前端UI的访问端口 - "6831:6831/udp" # 接收span数据的Agent UDP端口 - "6832:6832/udp" - "5778:5778"
2. 检查应用容器的Jaeger环境变量是否正确
你用Configuration.fromEnv()来初始化Tracer,所以必须给demo容器传递正确的环境变量,让客户端能找到Jaeger Agent:
在demo服务的compose配置里添加这些环境变量:
demo: build: . environment: - JAEGER_AGENT_HOST=jaeger # 用Jaeger服务的名称当主机名,Docker Compose会自动解析 - JAEGER_AGENT_PORT=6831 - JAEGER_SERVICE_NAME=demo-service # 给你的服务起个名字,方便在Jaeger UI里识别 depends_on: - jaeger # 确保Jaeger先启动
验证环境变量是否生效:进入demo容器执行printenv命令,看看上面几个变量是否存在且正确:
docker exec -it <你的demo容器ID或名称> printenv
3. 调整Jaeger的采样策略
默认的概率采样策略(采样率0.001,也就是千分之一的请求会被追踪)可能导致你看不到数据。可以强制所有请求都被采样,添加这两个环境变量到demo服务:
environment: # ...其他变量 - JAEGER_SAMPLER_TYPE=const - JAEGER_SAMPLER_PARAM=1
4. 确认Jaeger客户端依赖的兼容性
确保你的Spring Boot项目里用的Jaeger客户端版本和服务端(all-in-one镜像)兼容,推荐用官方的starter依赖,比如Maven:
<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId>opentracing-spring-jaeger-web-starter</artifactId> <version>3.2.2</version> <!-- 替换为最新稳定版 --> </dependency>
如果是手动创建Tracer,别在代码里硬编码agent的host/port,让fromEnv()去读取环境变量。
5. 测试容器间的网络连通性
进入demo容器,测试能否连通Jaeger的Agent端口:
- 先ping Jaeger服务,确认网络可达:
docker exec -it <demo容器ID> ping jaeger
- 再用telnet测试6831端口是否能连接:
docker exec -it <demo容器ID> telnet jaeger 6831
如果连接失败,检查Jaeger容器的端口是否正确暴露,或者是否有自定义网络配置导致隔离。
6. 查看日志找线索
- 查看demo应用的日志,看是否有Jaeger相关的错误(比如无法连接Agent的报错):
docker logs <demo容器ID>
- 查看Jaeger容器的日志,看是否有接收span的记录(比如
Processing span batch这类日志):
docker logs <jaeger容器ID>
如果Jaeger日志里有接收span的信息,那可能是UI没刷新或者服务名没匹配;如果没有,说明数据根本没传过去。
7. 确认Tracer初始化是否正确
可以在你的Tracer配置代码里加日志,打印读取到的配置,确认是否正确:
@Bean public Tracer jaegerTracer() { Configuration config = Configuration.fromEnv(); // 打印配置信息,方便排查 System.out.println("Jaeger Agent Host: " + config.getSenderConfiguration().getAgentHost()); System.out.println("Jaeger Agent Port: " + config.getSenderConfiguration().getAgentPort()); return config.getTracer(); }
然后看应用日志里是否输出了jaeger和6831,确认配置读取正确。
内容的提问来源于stack exchange,提问作者TheManawaha

