+-
跨线程发送TraceId

我们有一个遵循微服务架构的分布式应用程序。在我们的一个微服务中,我们遵循生产者 - 消费者模式。

生产者接收请求,将其持久保存到数据库,将请求推送到BlockingQueue并将响应发送回客户端。在单独线程上运行的使用者正在侦听阻塞队列。它获取请求对象的那一刻就对它执行特定的操作。

生产者收到的请求使用CompleteableFutures异步保存到数据库。

这里的问题是如何将TraceId转发到处理消费者线程内的requestObject的方法。由于消费者线程可能在响应发送给消费者之后很久才处理这些对象。

另外如何跨异步调用转发traceId?

谢谢

0
投票

这是一个有趣的问题。我认为您可以做的是将请求与其标题一起保留。然后在消费者方面,你可以像我们这样做的方式使用SpanExtractor界面 - https://github.com/spring-cloud/spring-cloud-sleuth/blob/v1.3.0.RELEASE/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java#L351(Span parent = spanExtractor().joinTrace(new HttpServletRequestTextMap(request));)。这意味着从HttpServletRequest我们提取值来构建跨度。然后,一旦你检索了Span,你可以在处理之前使用Tracer#continueSpan(Span)方法,然后在finally块中使用Tracer#detach(Span)。例如。

Span parent = spanExtractor().joinTrace(new HttpServletRequestTextMap(request));
try {
   tracer.continueSpan(parent);
   // do whatever you need
} catch(Exception e) {
  tracer.addTag("error", doSthWithTheExceptionMsg(e));
} finally {
  tracer.detach(parent); 
}