微服务架构中如何处理“外键”?

rak*_*hra 3 spring-boot microservices

关于微服务中的外键的快速问题。我已经尝试寻找答案。但是,他们没有给我我正在寻找的确切答案。

用例:每篇博文都会有很多评论。传统的单体应用会有评论表和博客文章的外键。但是在微服务中,我们将有两个服务。

服务 1:使用这些表字段(PostID、Name、Content)发布微服务

服务 2:具有这些表字段(CommentID、PostID、Cpmment)的评论微服务

问题是,我们在服务 2(评论微服务)中需要“PostID”吗?我想答案是肯定的,因为我们需要知道哪个评论属于哪个帖子。但是,它会产生紧耦合吗?我的意思是如果我删除服务 1(博客发布服务),它会影响服务 2(评论服务)吗?

Edw*_*rzo 5

我将使用另一个我更熟悉的例子来解释我相信大多数人会如何做到这一点。

考虑订单管理系统 (OMS) 和库存管理系统 (IMS)。

当客户在公司网站下订单时,我们要求 OMS 在后端创建订单条目(例如,通过 HTTP 端点)。

OMS 系统然后广播一个事件,例如OrderPlaced,其中包含客户订单的所有详细信息。我们可能有一个发布/订阅(例如 Redis)、一个队列(例如 RabbitMQ)或一个事件流(例如 Kafka)来放置事件(尽管这可以通过许多其他方式完成)。

问题是我们有一个或多个订阅者对此事件感兴趣。其中之一可能是 IMS,它负责在每次下订单时分配可用的最佳库存。

我们可以预期 IMS 会保留它在处理OrderPlaced事件时收到的相关订单信息的副本,这样它就不会一直向 OMS 询问订单的每一个细节。因此,如果 IMS 需要与订单连接,而不是调用 Order API 中的端点,它可能只是与它的本地订单表副本进行连接。

现在假设我们的客户打电话取消她的订单。然后,客户服务代表在 OMS Web 用户界面中取消了它。届时将OrderCanceled广播一个事件。猜猜谁在监听那个事件?正确,IMS 收到通知并相应地采取行动,逆转库存分配,甚至可能删除订单记录,因为在该域中不再需要它。

因此,如您所见,执行此操作的最佳方法是使用事件并复制其他域上的相关详细信息。

由于事件需要时间被相关方广播和处理,我们说 IMS 中的订单数据最终是一致的。

后续问题

问:那么,如果我在微服务中理解正确的话,我们更喜欢复制数据并获得更好的性能?那是什么概念?我的意思是我知道这个概念是扩展性和灵活性,但是当我们必须共享数据时,我们只会复制它?

并不真地。这绝对不是我的意思,尽管由于我在原始解释中对单词的选择不当,这听起来可能是这样。在我看来,您问题的核心在于对有界上下文的概念缺乏足够的理解。

在我的解释中,我的意思是指出 OMS 有一个称为订单的领域概念,但 IMS 也是如此。因此,它们都在其域内有一个实体来表示它。OMS 中的订单实体很有可能比 IMS 中相同概念的相应表示更丰富。

例如,如果我描述的系统不是用于零售,而是用于批发,那么我们系统中“销售订单”的相同概念对应于我们客户中“采购订单”的概念。所以你看,同样的数据,映射在不同的名字下,仅仅是因为在不同的有界上下文下,数据可能有不同的视角和含义。

因此,我们意识到我们模型中的给定概念可以在多个有界上下文中表示,可能是从我们无处不在的语言的不同角度和名称。

再举一个例子,OMS 需要了解客户,但 OMS 中客户的想法的表示可能与 CRM 中此类概念或实体的相同表示不同。在 OMS 中,客户的姓名、电子邮件、送货地址和帐单地址可能足以代表这一想法,但对于 CRM 而言,客户包含的内容更多。

另一个示例:IMS 需要知道客户的送货地址以选择最佳库存(例如,最靠近其最终目的地的设施中的库存),但可能不太关心帐单地址。另一方面,账单地址是支付管理系统 (PMS) 的基础。所以,IMS和PMS可能都有一个“订单”的概念,只是不完全一样,没有相同的含义或视角,即使我们存储的是相同的数据。

最后一个例子:会计系统出于会计目的关心库存,以便能够知道我们拥有多少,但也许会计并不关心库存在仓库内的具体位置,这是只有 IMS 关心的细节.

总之,我不会说这是关于“复制数据”,这是关于在您的有界上下文中适当地表示一个基本概念,并意识到模型中的某些概念可能在系统之间重叠并具有不同的表示,有时甚至以不同的名称和细节层次。这就是为什么我建议你多研究上下文映射的想法。

换句话说,从我的角度来看,假设“订单”的概念只存在于 OMS 中是错误的。我可能会说 OMS 是订单记录的主人,如果订单发生问题,我们应该让其他感兴趣的系统知道这些事件,因为他们关心其中的一些数据,因为其他系统可能有相关的映射概念订单,并且在对主记录中的更改做出反应时,他们可能也想更改他们的数据。

从这个角度来看,复制一些数据是对有界上下文进行适当设计的副作用,而不是其本身的目标。

我希望这能回答你的问题。

  • 那么,如果我对微服务的理解正确的话,我们更喜欢复制数据并获得更好的性能?是这个概念吗?我的意思是,我知道这个概念是可扩展性和灵活性,但是当我们必须共享数据时,我们只会复制它吗? (2认同)