【问题标题】:How to include CorrelationId in microservice architecture?如何在微服务架构中包含 CorrelationId?
【发布时间】:2017-01-20 08:06:00
【问题描述】:

我正在使用 ASP.NET Core Web api 创建一个微服务架构。所有的服务都是相互解耦的,可以部署在不同的环境中。每个服务都有自己的日志记录。当请求流经这些服务时,任何服务都可能失败,我们需要一种将一系列事件追溯到源头的方法,即使这意味着要遍历多个服务。
因此,为了处理这个问题,发起请求的服务会创建一个 CorrelationId 并将其传递给下一个服务。第二服务将其传递给第三服务,依此类推。如果发生异常,相应的服务会将异常消息与 CorrelationId 一起记录。

我想知道服务调用者传递相关 ID 的最佳位置是什么?

调用者应该在 HttpHeader 中传递相关 ID 还是应该将其作为部分方法参数传递,如下所示

这是被调用的服务

 public class RequestDTO
 {
    public string CorrelationId {get;set;}
    public string SomeOtherData {get;set;}
 }

 public Service2Controller:Controller
 {
    public Task<in> DoSomething(RequestDTO request)
    {
         // add the correlationid in current request Items collection
         // So global exception handling can access it and log it 
         // along with the exception

         HttpContext.Items.Add("CorrelationId", request.CorrelationId);
    }
 }

在上述方法中,如果在调用此方法之前出现异常,则 CorrelationId 将无法用于全局异常处理程序进行日志记录。

有什么建议吗?或替代方法

【问题讨论】:

  • 自定义标头很常见,因为它在反序列化等过程中绕过了问题。但是,为什么不也将它也传递到有效负载中。没有理由不能两者兼得。
  • @TomRedfern 是 typical 将自定义数据添加到 http 标头吗?
  • @TomRedfern 每个服务都可以部署到不同类型的环境中。我担心将自定义数据添加到 http 标头中可能会被主机服务器拒绝。托管服务器通常会检查未知标头吗?
  • 我还没有遇到无法处理自定义标头的 http 服务器。我们在我们的解决方案中使用自定义标头,其中包含用 java 和 .net 编写的服务,中间带有 jboss fuse。

标签: microservices asp.net-core-webapi


【解决方案1】:

相关标识符不应该是你自己添加的东西,一些发送消息的框架应该这样做。这样开发人员就不会忘记它,并且它在所有地方都有一致的行为。

在邮件标题中添加MessageId 和CorrelationId。在第一条消息上,两者都是相同的。在第二条消息中,CorrelationId 设置为上一条消息的 MessageId。

您还可以设置一个永远不会更改的唯一ConversationId,以跟踪来自一个发起者的所有消息。在使用 pub/sub 和/或回调消息的发起者时很有用。

【讨论】:

  • 嗨@dennis,上面的策略不是意味着您必须编写一个图形查询来查看单个事务的完整日志跟踪吗?即假装correlationID开始为1,并且消息ID = 1,对于下一条消息,您的策略建议新消息的消息ID = 2,并且correlationID = 1,下一条消息现在是3和2。现在没有办法看到所有使用correlationID 1 记录事务的消息。不是更好的策略是correlationID 总是与传入的correlationID 相同吗?
  • 这就是 ConversationId 的用途。这始终保持不变。 CorrelationId 将追溯哪个先前的消息(和处理程序)导致发送此消息。这正是 NServiceBus 所做的以及 ServiceInsight 如何创建整个消息流的流程图:docs.particular.net/serviceinsight/#flow-diagram
  • 换句话说,如果您有 1 个来自日志文件或消息头的 ConversationId,则可以使用该 ConversationId 进行查询并查找属于对话一部分的所有消息。然后使用 CorrelationId 追溯它们的发送顺序。
  • 好吧,这听起来很明智,但这似乎与其他地方给出的有关 x-request-id、x-correlation-id 和 request-id 的建议不同。也许这些名字是偶然相似的,因此令人困惑? (我很容易被误解。)这里讨论了 http 标头:我想要来自 http 客户端的 2 个跟踪 sagas 跨越所有服务和队列。有什么建议? stackoverflow.com/questions/56068619/….
  • 如果我理解正确,有两种选择。有了他们两个,一个用户、一个 WebAPI、一个后台进程,任何东西都可以开始发送消息。 1. 只发送一条消息。如果您使用 NServiceBus 或 MassTransit 之类的框架,则从一开始就添加标识符。否则你自己做。 2. 发送多条消息,它们都需要相同的conversationid/correlationid。这意味着你必须自己做,或者使用可用的选项。使用 NServiceBus,您可以使用 SendOptions。如果您通过 HTTP 发送数据,我不确定是否有任何支持。
猜你喜欢
  • 2014-01-08
  • 2015-12-26
  • 2018-09-11
  • 2019-08-19
  • 2021-11-02
  • 2016-11-23
  • 2018-03-29
  • 2019-03-23
相关资源
最近更新 更多