在SQS监听接收SNS后发布新SNS,如何传播TraceId?
使用Spring Cloud Sleuth在SNS/SQS间传播TraceId
核心思路
Sleuth默认支持AWS消息服务的链路追踪,但需要手动提取传入消息的TraceId并注入当前上下文,后续发送新SNS消息时,Sleuth会自动将上下文里的TraceId携带到新消息中。
具体实现步骤
1. 依赖配置
确保项目已引入spring-cloud-starter-sleuth和AWS消息相关依赖:
<!-- Maven示例 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-aws-messaging</artifactId> </dependency>
如果用AWS SDK v2,需额外添加:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-aws2</artifactId> </dependency>
2. 提取并注入TraceId到Sleuth上下文
在SQS监听器方法中,从SNS消息的MessageAttributes里取出TraceId,手动创建Span并绑定到当前上下文:
import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.Span; import org.springframework.messaging.handler.annotation.Header; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.stereotype.Component; import com.amazonaws.services.sns.model.MessageAttributeValue; import java.util.Map; @Component public class SqsMessageListener { private final Tracer tracer; private final SnsMessagingTemplate snsMessagingTemplate; public SqsMessageListener(Tracer tracer, SnsMessagingTemplate snsMessagingTemplate) { this.tracer = tracer; this.snsMessagingTemplate = snsMessagingTemplate; } @MessageMapping("your-target-queue-name") public void handleIncomingSnsMessage(String payload, @Header("MessageAttributes") Map<String, MessageAttributeValue> messageAttributes) { // 从消息属性中提取上游传入的TraceId(键名以上游实际设置为准) String incomingTraceId = messageAttributes.get("TraceId").getStringValue(); // 创建新Span并指定TraceId,绑定到当前上下文 Span span = tracer.nextSpan().name("process-sns-message").traceId(incomingTraceId); try (Tracer.SpanInScope scope = tracer.withSpan(span.start())) { // 执行业务处理逻辑 processMessagePayload(payload); // 发送新SNS消息,Sleuth自动将当前TraceId注入消息属性 publishNewSnsMessage("your-target-topic-arn", "new-message-content"); } finally { span.end(); } } private void processMessagePayload(String payload) { // 自定义业务处理逻辑 } private void publishNewSnsMessage(String topicArn, String message) { snsMessagingTemplate.convertAndSend(topicArn, message); } }
3. 自定义TraceId属性名(可选)
如果需要指定TraceId在SNS消息属性中的键名,可在application.yml中配置:
spring: cloud: sleuth: propagation: aws: enabled: true trace-id-name: TraceId # 替换为你需要的属性键名
4. 验证链路传播
发送新SNS消息后,下游接收方可以从消息的MessageAttributes中获取到相同的TraceId,以此确认链路传播成功。
注意事项
- 确保上游发送SNS消息时,已将TraceId正确放入
MessageAttributes中,否则无法提取。 - 不要手动在消息体中传递TraceId,利用Sleuth上下文自动注入更符合链路追踪规范。
内容的提问来源于stack exchange,提问作者Thiago Souza
相关产品推荐
相关产品推荐

