环境搭建:部署Jaeger(单机模式)

好了,这一章咱们得来点实操了。
前面我们把理论讲得挺透的,也聊了分布式追踪的概念。但光说不练假把式对吧?
这一章,我们就亲手把 Jaeger 搭起来。我会选最简单的模式——单机部署,让你先跑起来再说。

什么是 Jaeger 单机模式?

说白了,单机模式就是把 Jaeger 所有的组件打包进一个进程里。
你启动一个二进制文件,就能同时得到 Agent、Collector、Query 服务和 UI 界面。
对我们学习和前期调试来说,这招太实用了。

我之前在项目里第一次接触 Jaeger 时,就用的这个模式。五分钟就跑通了,当时心里就踏实了。

  • all-in-one:没错,官方就叫这个名字。一个可执行文件搞定一切。
  • 存储默认是内存:数据存在内存里,重启就丢了。但做实验完全够用。
  • 端口占用:16686 给 UI,6831/6832 给 Agent,14250 给 Collector 的 gRPC。
很多初学者一上来就搞生产级的高可用部署,结果配置堆了一大堆,最后连数据都看不到。我的建议是:先单机跑通,再谈扩展。

前置准备:你只需要一个终端

咱们的目标是用最小代价跑起来,不做那些花里胡哨的准备工作。你只需要:

  1. 能联网的 Linux 或 macOS 机器(Windows 用 WSL 也行,不过我用得少,建议你先在 Linux 上试)。
  2. 装好 curl 和 wget,用来下载文件。
  3. 保证 16686、6831、14250 端口没被占用。

如果手边没有合适的机器,用 Docker 也行。但我个人更偏爱直接跑二进制,因为你能直观看到进程和日志。后面我会附上 Docker 命令,不过不是必选项。

下载 & 启动 Jaeger 二进制

这一步其实很简单。直接去 Jaeger 的 GitHub Releases 页面,找到最新版,下载对应系统的压缩包。

这里我直接贴出命令行吧:

# 下载 Linux amd64 版本
wget https://github.com/jaegertracing/jaeger/releases/latest/download/jaeger-1.60.0-linux-amd64.tar.gz

# 解压
tar -xvf jaeger-1.60.0-linux-amd64.tar.gz

# 进入目录
cd jaeger-1.60.0-linux-amd64

# 启动 all-in-one
./jaeger-all-in-one --collector.zipkin.host-port=:9411

嗯,等一下。如果你用的 macOS 或者 arm 架构,就把下载链接里的 linux-amd64 换成 darwin-amd64 或 darwin-arm64。

我第一次用的时候,就是因为忘了改架构,下载了 amd64 版本在 M1 上跑,结果弹出一堆非法指令错误…… 哎哟,反正还是得仔细看版本号。

我曾经碰到过一个坑:启动后终端一直打印日志,但端口 16686 就是访问不了。查了半天才知道,是云服务器上的防火墙没开那个端口。所以啊,如果你的 Jaeger 跑在远程机器上,别忘了检查安全组或 iptables。

启动后,你应该会看到类似这样的日志输出:

{"level":"info","msg":"Starting Jaeger all-in-one","service":"jaeger-all-in-one","version":"1.60.0"}
{"level":"info","msg":"Starting agent","service":"jaeger-agent","admin":{"address":":14269"},"zipkin":{"thrift-addr":":5775"},"collector":{"http-addr":":14268","grpc-addr":":14250"}}
{"level":"info","msg":"Starting query service","service":"jaeger-query","port":16686,"health-check":":16687"}

看到这堆日志,就说明 Jaeger 已经在干活了。

验证:打开浏览器看看

先别急着写代码。我们用浏览器确认一下服务是不是真的正常。

打开浏览器,输入:

http://你的机器IP:16686

你应该能看到 Jaeger UI 的漂亮界面。
虽然现在里面空空如也,但说明咱们的搭建成功了。

接着,我们手动送一条追踪数据来测试一下:

curl -X POST http://localhost:14268/api/traces \
  -H "Content-Type: application/json" \
  -d '{
        "id": "1234567890abcdef",
        "traceId": "1234567890abcdef1234567890abcdef",
        "spans": [
          {
            "traceId": "1234567890abcdef1234567890abcdef",
            "spanId": "abcdef1234567890",
            "operationName": "test-span",
            "startTime": 1700000000000000,
            "duration": 1000,
            "tags": [
              {"key": "service", "type": "string", "value": "my-app"}
            ]
          }
        ]
      }'

刷新 UI,在 Service 下拉框中选中 my-app,你就能看到一条追踪记录了。

验证这一步很多人都跳过,但我建议你别省。很多时候你以为是 SDK 没接入好,其实是 Jaeger 服务本身有问题。先确认 Jaeger 能收数据,再排查应用代码。

配置存储:从内存漂到磁盘

默认的 in-memory 存储,一重启就丢数据。如果你想把数据保持久一点,用 Badger 吧——这是个内嵌的键值存储,很轻量,适合单机场景。

启动时加上存储参数就行:

./jaeger-all-in-one \
  --collector.zipkin.host-port=:9411 \
  --badger.ephemeral=false \
  --badger.directory.key=/tmp/jaeger-badger/key \
  --badger.directory.value=/tmp/jaeger-badger/value

这里要注意几个点:

参数 作用 我的建议
--badger.ephemeral=false 关闭内存模式,数据写入磁盘 开发环境建议设为 false
--badger.directory.key 索引数据目录 确保该目录存在且有写权限
--badger.directory.value 实际数据目录 建议和 key 目录分开

重启 Jaeger 后,数据就不会丢了。重启后再去查之前的 trace,还在。

我通常建议,如果你只是做教程或写 demo,用内存存储就够了,省事。但如果你打算让团队成员连续用几周,还是切到 Badger 或 Elasticsearch 好。不然谁忘了重启一下,历史追踪全没了,大家会来找你哭的。

总结一下这个部署流程

我们刚才干了几件事:下载二进制、解压、启动 all-in-one、验证端口和 UI、手动发一条 trace 测试,最后还配置了 Badger 持久化。

你看,把一个分布式追踪系统的核心跑起来,其实就这几步。

下面这张图,把单机模式下的 Jaeger 核心组件和交互画清楚了:

Jaeger单机模式核心架构 Jaeger 单机模式(all-in-one)架构 微服务 A 微服务 B Jaeger Agent 链路数据上报 all-in-one 进程 Collector Query 服务 UI (16686) 说明: 1. 微服务通过 Agent 上报链路数据,Agent 默认监听 6831/6832 端口。 2. Collector 负责处理和存储,默认使用内存或 Badger。 3. 开发者通过 16686 端口的 UI 查询追踪数据。

你看这张图,逻辑很清楚。
微服务产生的 span 数据,通过 Agent 送到 Collector,Collector 存下来,最后 UI 给你展示出来。整个过程一条链,没有多余的中间件。