TT Lab
开始
学习 学习路径 课程

分布式链路断掉的地方

把断掉的追踪接起来

在 TT Lab 中继续学习

目标

跟踪只要有一处没有接上,整条就完全没用了。而且断开时不会报错,所以在打开仪表板看之前,没有人会知道。

本实验会给你三个已经断开的服务,让你把它们接起来。

开始

cp /opt/lab/trace/* . && chmod +x run.sh
./run.sh            # a → b → c 로 요청 하나를 흘린다
python3 tree.py     # 이어졌는지 본다

文件

文件 作用
svc.py 单个服务。其中有一个 bug
run.sh 启动三个服务并发送一个请求
tree.py 读取日志,判定是否已经接上

需要了解

run.sh 在终止服务时不使用 pkill -f svc.py。这个匹配模式也会命中运行该脚本的 shell 的命令行,从而把自己杀掉。它改为记下 PID,只终止这些进程。

traceparent

00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
│  │                                │                │
│  trace id (16바이트)               부모 span         플래그
버전

步骤

  1. 确认跟踪断开 → 01-broken.txt
  2. 在哪里、为什么断开 → 02-where.md
  3. 把它接起来 → 由评分器亲自运行来确认
  4. 读懂格式 → 04-format.md
  5. 采样一致性 → 05-sampling.txt
  6. 并发请求 → 06-concurrent.txt
  7. 总结 → 07-notes.md

亲眼看到断开的跟踪

把 /opt/lab/trace/ 复制到工作目录,运行 ./run.sh,并把 python3 tree.py 的结果保存到 01-broken.txt。

从 cp /opt/lab/trace/* . && chmod +x run.sh 开始。一个请求会流经三个服务(a→b→c)。

症状与真实现场完全一样——每个服务都在正常发送跟踪数据,但它们并没有连起来。仪表板上会堆满只有一个跨度的跟踪。

指出在哪里、为什么断开

阅读 svc.py,在 02-where.md 中写出问题出在哪一行,并说明为什么这一行会让跟踪断开。

看一看向下一个服务发送请求的位置。接收方发现没有请求头时,会新建一个跟踪 ID——这是正确的行为。问题出在发送方。

跟踪断开的位置几乎总是在调用方。无论怎么看接收方的代码,都找不到原因。

把它们接成一条

修改 svc.py,让三个服务共享同一个跟踪 ID,并且父子关系相连。

在发出的请求上加上 traceparent 请求头。格式为 버전-trace-내span-플래그(占位符依次为版本、跟踪 ID、自己的跨度、标志位)。放在父级位置的不是收到的父跨度,而是当前自己的跨度——这里很容易出错。

评分器会亲自运行,确认跟踪 ID 只有 1 种、根只有 1 个、找不到父级的跨度为 0 个。

把 traceparent 拆开来读

在 04-format.md 中写出 traceparent 的四个部分各自是什么,并以第 3 步日志中的一个实际值为例。

00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01。从前往后依次是版本、跟踪 ID(16 字节)、父跨度(8 字节)、标志位。

长度是固定的,所以肉眼也能验证——跟踪 ID 如果不是 32 个字符,当场就能判定有错。

采样只决定一次

确认即使根服务以标志位 00(不采集)起始,三个服务留下的也是相同的标志位,并把结果保存到 05-sampling.txt。

决定只在根处做一次,然后原样往下传递。中途重新决定,跟踪就会变成半条——前半部分被采集、后半部分缺失的跟踪,对调试的妨碍无出其右。

在根处更改起始标志位后运行,并保存 tree.py 输出中的标志位那一行。

同时发送多个请求时会不会混在一起

同时发送三个请求,确认每个请求都各自构成完整的跟踪,并把结果保存到 06-concurrent.txt。

参考 run.sh 启动服务后,用 & 同时发送三个 curl。结果正确时,跟踪 ID 有 3 种,每条跟踪有 3 个跨度,根有 3 个,孤儿为 0 个。

这里出问题的典型原因是把上下文放进全局变量。用一个请求测试时一切正常,流量一上来,跟踪就会相互混在一起。这就是每种语言都有按请求存储的机制的原因。

总结三点

在 07-notes.md 中至少写三行:跟踪断开的位置、父级位置放什么、采样决定在哪里做。

正文中必须包含 호출、부모、샘플링。