Jaeger Hot R.O.D. 示例应用完全指南:用 OpenTelemetry 搭建微服务分布式追踪演示
【免费下载链接】jaegerCNCF Jaeger, a Distributed Tracing Platform项目地址: https://gitcode.com/GitHub_Trending/ja/jaeger
Hot R.O.D.(Rides on Demand)是 Jaeger 项目内置的经典分布式追踪演示应用,由多个微服务组成,用于展示如何使用 OpenTelemetry API 与 SDK 对真实业务场景进行插桩。本文基于仓库中的 examples/hotrod/README.md 展开,覆盖四种运行方式(docker compose、Kubernetes、源码编译、独立 Docker 容器)、全部命令行参数、指标暴露方式以及 Jaeger UI 联动配置,并深入对应源码,帮助你快速上手并理解 Hot R.O.D. 的底层实现。读完本文,你将能够在本机或 Kubernetes 上完整跑起 Hot R.O.D. + Jaeger 的演示环境,并通过 Jaeger UI 分析微服务调用链、定位延迟与并发问题。
注意:自 Jaeger v1.42.0 起,Hot R.O.D. 已从 Jaeger 客户端 SDK 升级为 OpenTelemetry SDK 进行 Trace 上报(见 README),因此本演示同时是学习 OpenTelemetry 插桩的最佳实战素材。
Hot R.O.D. 是什么:四个微服务的"打车"场景
Hot R.O.D. 模拟一个按需出行(网约车)业务,由前端(frontend)、客户(customer)、司机(driver)和路线(route)四个微服务协作完成一次打车请求:
- frontend:Web 前端服务,接收用户请求,编排后续调用(默认端口
8080); - customer:客户服务,模拟从 MySQL 读取客户档案(默认端口
8081); - driver:司机服务,模拟通过 Redis 查找最近的司机(默认端口
8082); - route:路线服务,模拟路径计算(默认端口
8083)。
从源码看,四个服务的启动逻辑集中在 examples/hotrod/cmd 目录下:入口 main.go 调用cmd.Execute(),而 all.go 中的all子命令会并发启动全部服务:
go customerCmd.RunE(customerCmd, args) go driverCmd.RunE(driverCmd, args) go routeCmd.RunE(routeCmd, args) return frontendCmd.RunE(frontendCmd, args)各服务的延迟参数(模拟 MySQL / Redis / 路线计算耗时)定义在 services/config/config.go 中,例如MySQLGetDelay = 300 * time.Millisecond、RedisFindDelay = 20 * time.Millisecond、RouteCalcDelay = 50 * time.Millisecond,并配有标准差参数以模拟真实抖动。
为什么值得运行它:演示的核心特性
依据 README,Hot R.O.D. 主要演示以下能力:
- 数据驱动的依赖关系图:通过实际 Trace 数据自动发现整个系统的微服务架构;
- 请求时间线与错误查看:直观理解一次请求在各服务间的流转过程;
- 定位延迟与并发不足的根源:通过 Trace 找出性能瓶颈;
- 高上下文化日志(Highly contextualized logging):日志与 Trace 关联,便于排查;
- Baggage 传播:
- 诊断请求间争用(排队)问题;
- 统计服务内各环节耗时;
- 使用 opentelemetry-go-contrib 开源库:以最小代码改动完成 HTTP 与 gRPC 请求的自动插桩。
其中"排队 / 并发不足"的演示非常经典:仓库在 services/config/config.go 中通过MySQLMutexDisabled控制是否用互斥锁模拟"连接池大小仅为 1"的错误配置,当锁未禁用时,多个并发请求会在同一把锁上排队,从而在 Jaeger UI 的 Trace 中呈现出明显的等待段,这就是 Baggage 传播用于诊断请求间争用的典型场景。
运行方式一:docker compose 一键启动(推荐)
这是最省事的启动方式,Jaeger 后端与 HotROD 应用会被一起拉起:
- 获取
docker-compose.yml(仓库内版本见 examples/hotrod/docker-compose.yml); - 可选:从 Jaeger 官方下载页获取最新 Jaeger 版本号,通过环境变量
JAEGER_VERSION传入。如果不指定,docker compose会使用latest标签——首次拉取没问题,但镜像进入本地仓库后latest标签不会自动更新,可能长期运行旧版本甚至不兼容的 Jaeger 与 HotROD 组合; - 启动:
JAEGER_VERSION=2.14.0 docker compose -f path-to-yml-file up- 访问 Jaeger UI(http://localhost:16686)与 HotROD 应用(http://localhost:8080);
- 关闭与清理:
docker compose -f path-to-yml-file down仓库内 docker-compose.yml 展示了完整编排:jaeger服务暴露16686(UI)、16687、4317(OTLP gRPC)与4318(OTLP HTTP)端口;hotrod服务暴露8080与8083,并通过环境变量OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318将 Trace 通过 OTLP/HTTP 上报到 Jaeger,同时depends_on: jaeger保证后端先启动。你还可以通过REGISTRY与HOTROD_VERSION变量定制镜像仓库与 HotROD 版本(注释示例:JAEGER_VERSION=2.0.0 HOTROD_VERSION=1.63.0 docker compose up)。
README 建议优先尝试 Jaeger v2,其入口与配置见 cmd/jaeger 目录。
运行方式二:Kubernetes 部署
仓库在 examples/hotrod/kubernetes 目录下提供了 Kustomize 清单,部署与清理命令如下:
kustomize build ./kubernetes | kubectl apply -f - kubectl port-forward -n example-hotrod service/example-hotrod 8080:frontend # In another terminal kubectl port-forward -n example-hotrod service/jaeger 16686:frontend # To cleanup kustomize build ./kubernetes | kubectl delete -f -随后同样通过 http://localhost:16686(Jaeger UI)与 http://localhost:8080(HotROD)访问。
运行方式三:分别启动 Jaeger 后端与 HotROD
启动 Jaeger 后端(内嵌内存存储)
Jaeger 后端以 Docker 容器形式发布,内置内存存储,无需额外数据库:
docker run \ --rm \ --name jaeger \ -p4318:4318 \ -p16686:16686 \ -p14268:14268 \ jaegertracing/jaeger:latest端口说明:
4318:OTLP HTTP 接收端,HotROD 通过它上报 Trace;16686:Jaeger UI 与查询 API;14268:Jaeger 兼容的 Thrift HTTP 接收端。
启动后 Jaeger UI 位于 http://localhost:16686。
从源码运行 HotROD
git clone git@github.com:jaegertracing/jaeger.git jaeger cd jaeger go run ./examples/hotrod/main.go allgo run会编译并直接运行 examples/hotrod/main.go,all子命令一次性拉起全部四个服务。
从 Docker 运行 HotROD
docker run \ --rm \ --link jaeger \ --env OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318 \ -p8080-8083:8080-8083 \ jaegertracing/example-hotrod:latest \ all--link jaeger:将 HotROD 容器与上一步的 Jaeger 容器连接(同主机场景);OTEL_EXPORTER_OTLP_ENDPOINT:指定 OTLP 上报端点;-p8080-8083:一次性映射四个服务的全部端口;- 末尾
all:同源码运行,启动全部服务。
然后打开 http://127.0.0.1:8080 使用应用。
指标(Metrics)暴露
HotROD 默认以 Go 的expvar格式暴露指标,也可通过-m prometheus标志切换为 Prometheus 格式:
- expvar:
curl http://127.0.0.1:8080/debug/vars - Prometheus:
curl http://127.0.0.1:8080/metrics
从源码看,指标工厂在 cmd/root.go 中初始化:metricsFactory = prometheus.New().Namespace(metrics.NSOptions{Name: "hotrod", Tags: nil}),即以hotrod为命名空间。注意 README 中提到的-m prometheus标志对应的指标切换逻辑,可结合 internal/metrics 下的实现理解(默认工厂仍为 expvar 风格,Prometheus 通过同一 Factory 接口接入)。
与 Jaeger UI 联动:自定义"查找 Trace"链接地址
HotROD 的 Web UI 可以为每次请求生成跳转到 Jaeger UI 查找对应 Trace 的链接。默认使用 http://localhost:16686;若 Jaeger UI 部署在其他地址,可通过-j <address>标志覆盖:
go run ./examples/hotrod/main.go all -j http://jaeger-ui:16686该标志在 cmd/flags.go 中定义为--jaeger-ui/-j,默认值http://localhost:16686,并最终传入前端服务的options.JaegerUI(见 cmd/frontend.go),由前端服务在渲染页面时拼接出指向 Jaeger UI 的查询链接。
完整命令行参数速查
HotROD 使用 Cobra 命令行框架,全部标志定义于 cmd/flags.go。除上述-j外,常用参数如下:
| 参数 | 简写 | 默认值 | 说明 |
|---|---|---|---|
--otel-exporter | -x | otlp | OpenTelemetry 导出器(otlp或stdout),设为stdout可将 Trace 打印到控制台便于调试 |
--fix-db-query-delay | -D | 300ms | 模拟 MySQL 查询的平均延迟 |
--fix-disable-db-conn-mutex | -M | false | 禁用守护数据库连接的互斥锁(该锁用于模拟大小为 1 的错误连接池,引发排队现象) |
--fix-route-worker-pool-size | -W | 3 | 查询 route 服务的 worker 池大小 |
--customer-service-hostname | — | 0.0.0.0 | customer 服务监听地址 |
--driver-service-hostname | — | 0.0.0.0 | driver 服务监听地址 |
--frontend-service-hostname | — | 0.0.0.0 | frontend 服务监听地址 |
--route-service-hostname | — | 0.0.0.0 | route 服务监听地址 |
--customer-service-port | -c | 8081 | customer 服务端口 |
--driver-service-port | -d | 8082 | driver 服务端口 |
--frontend-service-port | -f | 8080 | frontend 服务端口 |
--route-service-port | -r | 8083 | route 服务端口 |
--basepath | -b | / | 前端服务的基础路径(反向代理场景常用) |
--jaeger-ui | -j | http://localhost:16686 | 生成"查找 Trace"链接所用的 Jaeger UI 地址 |
--verbose | -v | false | 开启 Debug 级别日志 |
上述参数的生效过程可参考 cmd/root.go 的初始化逻辑:-D、-M、-W会分别覆盖config.MySQLGetDelay、config.MySQLMutexDisabled、config.RouteWorkerPoolSize;各服务主机名与端口若被修改,也会记录到日志中,便于确认实际监听地址。因此你可以用-D 1s -M故意放大 MySQL 延迟并保留互斥锁,快速制造出明显的排队 Trace,直观验证 README 中"诊断请求间争用"的演示效果。
小结:一套可复用的 OpenTelemetry 学习环境
Hot R.O.D. 的价值在于它把 OpenTelemetry 的 Trace、Baggage、Metrics 与真实微服务架构结合成了一个可交互的演示系统。通过 examples/hotrod/README.md 提供的四种运行方式,你可以在几分钟内搭建起完整的 Jaeger + 多服务演示环境;而结合本仓库源码(cmd、services/config/config.go、docker-compose.yml),你还能进一步理解 OTLP 上报、Baggage 传播、队列争用模拟等底层机制,将其作为日常学习或内部培训的实战样板。
【免费下载链接】jaegerCNCF Jaeger, a Distributed Tracing Platform项目地址: https://gitcode.com/GitHub_Trending/ja/jaeger
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考