现场是这样的。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 父子关系正确,链路图上两段连成一条。
异步链路的断点在消息边界,生产者注入和消费者提取必须成对实现,只做一半等于没做。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
