现场是这样的。HTTP 入口的 trace 能看到,投递到队列后的消费链路变成另一个 trace,消息体里没有 traceparent 字段,故障时两段日志对不上。

中间走过弯路,把「线程池切换时上下文没有传递」当成主因,改完现象没变。

把日志和配置对完,能解释这个现象的基本就这几处。投递消息时没把 trace 上下文写进消息头;消费端没有从消息里 extract 上下文;中间件版本不兼容,注入的字段被丢掉。

动手时先看消息体里有没有上下文字段

python peek_queue.py --queue jobs --limit 3 --show-headers

发送时注入标准的 traceparent

carrier = {}; trace.inject(carrier); producer.send(body, headers=carrier)

消费端先 extract 再开 span

ctx = trace.extract(headers); with trace.start_as_current_span('consume', context=ctx): handle(msg)

剩下的就是按 trace_id 核对两段是否连上

python trace_check.py --id 4bf92f3577b34da6 --expect-spans 2

排查用的命令都是临时敲的,没有写成脚本,事后才整理。

别只看报错消失,验证要多做一步。同一条业务消息的入口与消费端在同一个 trace_id 下,span 父子关系正确,链路图上两段连成一条。

异步链路的断点在消息边界,生产者注入和消费者提取必须成对实现,只做一半等于没做。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189