如何使用Jaeger基于消息ID追踪特定异步消息的全链路耗时
当然可以!这种异步消息链路的追踪是Jaeger的经典应用场景之一,完全可以基于你的唯一消息ID实现全链路的追踪和耗时统计,我给你梳理下具体的实现思路:
核心原理
异步链路追踪的关键是在消息传递过程中携带并传递Jaeger的追踪上下文,把每个服务的Span和同一个消息ID绑定,最终形成一条完整的Trace链路。不需要依赖同步调用的请求响应,只需要在每个消息的属性中附加追踪上下文信息即可。
具体实现步骤
1. ServiceA 发送SQS消息时注入追踪上下文
- 在ServiceA中,启动一个新的Span,比如命名为
ServiceA.send_sqs_message,用来记录消息发送的动作 - 使用Jaeger的
TextMapPropagator(或者你配置的其他Propagator),将当前Span的追踪上下文(Trace ID、Span ID、采样标记等)序列化成键值对格式的字符串 - 将序列化后的追踪上下文,以及你的唯一消息ID,作为自定义属性添加到SQS消息中(比如属性名设为
trace-context和message-id) - 发送完消息后,结束这个Span(注意:这个Span的结束只是标记ServiceA的发送动作完成,不代表整个链路结束)
2. ServiceB 消费SQS并传递上下文到SNS
- ServiceB从SQS接收到消息后,先从消息属性中提取
message-id和trace-context - 用
TextMapPropagator解析trace-context,重建出ServiceA的Span上下文,以此为父上下文启动一个新的子Span,命名为ServiceB.process_sqs_message - 在这个Span中添加一个Tag:
message.id: {你的消息ID},把Span和消息ID绑定起来 - ServiceB处理完消息后,发送到SNS时,同样将当前Span的追踪上下文序列化,和消息ID一起添加到SNS消息的自定义属性中
- 处理完成后结束ServiceB的Span
3. ServiceC 消费SNS消息完成链路
- ServiceC从SNS接收到消息后,提取
message-id和trace-context - 解析上下文后启动子Span,命名为
ServiceC.process_sns_message,同样添加message.id的Tag - 处理完消息后结束这个Span,至此整个异步链路的Trace就完整了
如何查询特定消息ID的全链路耗时
在Jaeger UI的搜索栏中,直接输入message.id:{你的目标消息ID},就能筛选出所有关联这个消息的Span。你可以在Trace详情中看到:
- 从ServiceA发送消息,到ServiceC处理完成的全链路总耗时
- 每个服务的处理耗时(比如ServiceB从接收SQS到发送SNS的时间,ServiceC处理SNS消息的时间)
- 消息在队列/主题中的等待时间(通过Span的开始时间差可以计算出来)
注意事项
- 确保所有服务使用相同的Propagator配置(比如Jaeger默认的
jaeger格式,或者兼容的b3格式),否则不同服务之间无法正确解析追踪上下文 - 如果消息存在重试机制,每次重试都要使用同一个追踪上下文,不要生成新的Trace ID,否则链路会断裂成多个独立的Trace
- 不建议直接用消息ID作为Jaeger的Trace ID(除非你的消息ID完全符合Jaeger的Trace ID格式:16或32字节的十六进制字符串),最好还是用Jaeger自动生成的Trace ID,通过Tag关联消息ID,这样更稳妥
内容的提问来源于stack exchange,提问作者Julio
相关产品推荐
相关产品推荐

