我一直在考虑使用RabbitMQ进行跨服务消息传递。我已经能够使用Spring注释配置我们的Exchange / Queues / DLX等。示例(简单)队列侦听器:
@RabbitListener(queues = RabbitMessageType.QueueNames.SMS_NOTIFICATIONS)
public void receive1(Message message) throws Exception {
RabbitMessageDto messageDto = OBJECT_MAPPER.readValue(message.getBody(), RabbitMessageDto.class);
SmsNotificationDto payload = OBJECT_MAPPER.readValue(messageDto.getPayload(), SmsNotificationDto.class);
log.info(payload.getMessage());
}
我正在使用spring-cloud-sleuth生成correlationIds / traceIds,当使用HTTP请求与其他服务进行通信时会保留这些,这使我们能够在各种微服务的日志中跟踪给定的ID。
虽然我可以获取当前的traceId并将其插入我的DTO:
@Autowired
private Tracer tracer;
private RabbitMessageDto createRabbitMessageWithPayload(String messageType,
String messageVersion,
Object payload) {
return new RabbitMessageDto.Builder()
.withTraceId(tracer.getCurrentSpan().getTraceId())
.withDtoName(messageType)
.withDtoVersion(messageVersion)
.withPayload(payload)
.build();
}
我找不到在接收方法中设置traceId的方法。
谷歌继续把我带到春天的云流和春天的云流启动兔子;文档似乎表明它可以自动插入/设置traceIds,但我根本不熟悉spring-cloud-stream,并且没有找到特别有用的文档。所以,我很乐意回答以下问题:
答案 0 :(得分:0)
所以,如果有人想到设置侦探traceId上下文,我们想出了以下解决方案:
@Autowired Tracer tracer;
private void someMethod(long traceId) {
Span span = Span.builder()
.traceId(traceId)
.spanId(new Random().nextLong())
.build();
tracer.continueSpan(span);
// do work
tracer.closeSpan(span);
}
应该注意的是,所有文档都说明一旦你完成它就应该关闭一个跨度。上面的do work部分应该用try / catch / finally块包装,以确保关闭它。
在span仍然打开的情况下调用的任何方法都将继承traceId。
修改强>
我还应该说,似乎更好的解决方案是用spring-cloud-stream替换Spring AMQP库;据我所知,这应该自动包含兔子消息中的traceId(correlationId)并将其设置在另一端。但是,我没有机会测试这个。