LabHub
学习 学习路径 课程

微服务架构

验证关联 ID 的传播

在 LabHub 中继续学习

目标

手动创建 W3C traceparent 并将其传播到三级服务链中,再按跟踪 ID 关联日志,还原单个请求的路径。

为什么重要

如果仅用“因为它是第三种信号,所以有必要”来解释分布式跟踪,采用工作就会失败。必须知道它究竟能回答什么问题。假设十个服务的 p99 全都正常,但用户界面却需要 2 秒——在这种情况下,指标从原理上就无能为力。因为指标是聚合值,无法还原单个请求的路径。一个请求中执行 340 次耗时 4ms 的查询所造成的 N+1 问题,也绝不会出现在指标中,因为每次查询都很快。本实验不使用 SDK,只通过三个请求头片段来还原这条路径,让你今后接入 OpenTelemetry 时,能够在理解实际发生了什么的基础上进行接入。

步骤

  1. 使用 /opt/app/chain.py 启动网关(8120)、订单(8121)、库存(8122)三个服务。GET http://127.0.0.1:8120/order 返回 200。
  2. 使用 /root/trace/gen.py 创建 traceparent,并将其作为一行保存到 /root/trace/tp.txt。格式必须为 00-<32hex>-<16hex>-01
  3. 使用该请求头调用网关。三个服务分别在 /root/trace/svc-<이름>.log 中留下 trace_id=<값>,且三个值必须全部相同。
  4. 每份日志中还要留下 span_id=<16hex>parent_span_id=<16hex>。三个服务的 span_id 必须各不相同。
  5. 使用 /root/trace/join.sh,只从三份日志中提取具有相同 trace_id 的行,并按时间顺序在 /root/trace/joined.log 中留下 3 行。
  6. 执行 /opt/app/brokenchain.sh 后,会在 8123/8124/8125 上启动第二条服务链,其中一个服务会丢弃请求头。每个服务在 /root/trace/broken-<이름>.log 中留下 svc=<이름> in_trace=<값> out_trace=<값>。找出传入跟踪 ID 与传出跟踪 ID 不同的服务,并将其名称作为一行写入 /root/trace/broken.txt
  7. /root/trace/selftime.txt 中写入 slowest=<서비스명> total_ms=<정수>self_ms=<정수> 两行。self 是总时长减去子区段后的值。

参考

启动三级链式服务

使用 /opt/app/chain.py 启动网关(8120)、订单(8121)、库存(8122)三个服务。GET http://127.0.0.1:8120/order 返回 200。

/opt/app/chain.py 会在作为参数传入的端口上启动,并通过环境变量接收下一跳地址。请按网关、订单、库存的顺序启动三个服务。

创建 traceparent 请求头

使用 /root/trace/gen.py 创建 traceparent,并将其作为一行保存到 /root/trace/tp.txt。格式必须为 00-<32hex>-<16hex>-01

用连字符连接 2 位版本、32 位跟踪 ID、16 位跨度 ID 和 2 位标志。全部必须是小写十六进制。

将同一个跟踪 ID 传递到链路末端

使用该请求头调用网关。三个服务分别在 /root/trace/svc-<이름>.log 中留下 trace_id=<값>,且三个值必须全部相同。

让每个服务从收到的请求头中原样传递跟踪 ID,并将其记录在自己的日志中。

每一跳都更改跨度 ID

每份日志中还要留下 span_id=<16hex>parent_span_id=<16hex>。三个服务的 span_id 必须各不相同。

发送时,在父跨度 ID 的位置填入自己的跨度 ID。三份日志中的跨度 ID 全部不同时才是正常结果。

按跟踪 ID 关联三份日志

使用 /root/trace/join.sh,只从三份日志中提取具有相同 trace_id 的行,并按时间顺序在 /root/trace/joined.log 中留下 3 行。

按跟踪 ID 过滤各服务的日志文件,再按时间顺序拼接。关联结果必须恰好为 3 行。

找出传播中断的服务

执行 /opt/app/brokenchain.sh 后,会在 8123/8124/8125 上启动第二条服务链,其中一个服务会丢弃请求头。每个服务在 /root/trace/broken-<이름>.log 中留下 svc=<이름> in_trace=<값> out_trace=<값>。找出传入跟踪 ID 与传出跟踪 ID 不同的服务,并将其名称作为一行写入 /root/trace/broken.txt

其中有一个服务会故意丢弃请求头。只需找到跟踪 ID 发生变化的位置。

计算自身耗时

/root/trace/selftime.txt 中写入 slowest=<서비스명> total_ms=<정수>self_ms=<정수> 两行。self 是总时长减去子区段后的值。

从总持续时间中减去各个子跨度的时间。最慢的区段和自身耗时最长的位置可能不同。