Microservices 微服务体系结构中的耦合

Microservices 微服务体系结构中的耦合,microservices,coupling,Microservices,Coupling,在使用微服务体系结构开发应用程序时,我偶然发现了有关服务之间耦合的问题 这是订购产品的典型应用程序。有一个作为产品目录运行的服务是合理的。我们的JavaScript客户端可以请求该服务提供可用的产品,并在浏览器中显示它们。当用户单击产品时,我们必须创建订单。我们想管理其他服务中的订单。因此创建了一个订单-这意味着用户X订购了产品Y。在技术层面上,我们只是将用户id和产品id持久化到数据库中 总括而言,我们有: 产品服务 产品类别: 产品ID、产品名称 订单服务 订单类别: 订单ID、产品ID、用

在使用微服务体系结构开发应用程序时,我偶然发现了有关服务之间耦合的问题

这是订购产品的典型应用程序。有一个作为产品目录运行的服务是合理的。我们的JavaScript客户端可以请求该服务提供可用的产品,并在浏览器中显示它们。当用户单击产品时,我们必须创建订单。我们想管理其他服务中的订单。因此创建了一个订单-这意味着用户X订购了产品Y。在技术层面上,我们只是将用户id和产品id持久化到数据库中

总括而言,我们有:

产品服务 产品类别:
产品ID、产品名称

订单服务 订单类别:
订单ID、产品ID、用户ID、订单日期

现在让我们设想以下场景——在JavaScript客户端中,我们希望列出用户订购的所有产品。Orders服务为给定用户提供产品ID列表。但用户关心的是产品名称,而不是id。不幸的是,订单服务对产品名称一无所知

我们可以通过两种方式解决这个问题:

  • 简单地假设客户机负责获取其所需的信息。因此,在调用Orders服务并获取产品ID列表后,它会再次调用products服务,传递产品ID并获取相应的产品名称作为响应。然后,客户机将这两个响应组合成有用的内容。这种方法使我们的服务保持干净,不会将领域知识从一个服务泄漏到另一个服务。但它需要在客户端做更多的工作

  • 当要求订购产品时,订单服务会在后端呼叫产品服务。它检索产品名称,组装包含orderDate和productName的响应,并将其发送到客户端。客户机所要做的就是显示数据。这种方法的缺点是订单服务现在获得了更多关于产品的知识,而不是必要的知识

  • 订单服务中有关产品名称的重复信息。创建订单时,我们不仅传递产品id,还传递产品名称。这意味着Order类将如下所示: 订单类别:
    订单ID、产品ID、产品名称、用户ID、订单日期
    现在,我们可以轻松地提供有关订单的完整信息,而无需致电产品服务部。而且这次订单服务对产品的了解太多了。有利的是,订单服务可以提供相关数据,即使产品服务中断


这些方法中有哪一种可以被视为最佳做法?或者有不同的解决方案吗?

在eShopOnContainers示例()中,他们在创建订单项目时添加以下字段:

        public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, string pictureUrl, int units = 1)
但是,这会复制目录信息,因为这是记录的时间点快照。这比链接到原始数据要安全得多

在用户旅程的这一点上,您处于订单域中,如果用户正在查看订单,您可以提供目录链接。但是,订单服务应该能够独立运行。将产品信息链接回目录可防止订单服务拥有自己的数据


一个噩梦般的场景是目录中的价格变化。。。历史订单会发生什么情况?

复制信息。这不是真的。如果将来更改产品名称,用户应该看到什么?我同意,只复制所需的数据似乎是明智的选择。如果需要,您还可以考虑使用消息队列将产品名称或价格更改推送到篮子预订单中。订单完成后,有关产品的信息可能不会改变。同意。在订单完成之前,价格可能会发生变化。亚马逊就是这样运作的。篮子里的东西等价格不断变化。订单完成后,必须在时间点捕获。未告知客户,不得更改商定的价格。