微服务架构松耦合并发症

Micro-services architecture loose coupling complications

我对整个微服务潮流还很陌生。我一直在研究良好的微服务环境背后的架构和原则。

定义微服务的主要内容之一应该是每个服务的松耦合性质。 微服务 A 永远不应直接调用 微服务 B,否则您实际上是在创建一个失去架构模式提供的可扩展性的单体系统。

问题/例子

如果我开发一个 returns GUID(例如)的微服务,建议环境中的其他微服务可能会在需要时直接调用 GUID 服务是合理的。

我知道可以使用各种排队系统将数据从一项服务传递到另一项服务,但在我看来,它们主要用于插入、删除或更新。

我无法理解队列如何用于简单读取(如我的 GUID 示例)以及为什么您不直接从另一个微服务调用 GUID 服务。

注意:返回 GUID 只是一个示例,我知道大多数语言都能够在内部生成它们

如果对此有一些澄清,我们将不胜感激。

你不应该按原样遵守每条规则。

这条规则有很多例外,很多系统的实践证明它并不适用于每个案例或系统。

我不同意此限制,即 micro-service A 永远不应调用 micro-service B 作为一般规则,因为它并不适用于所有情况。我使用过多个系统 micro-services 而我们没有遵循它。

micro-service之间的通信:

您可以使用多种方式在 micro-service 之间进行通信,例如:

  1. 事件(使用队列)

  2. 命令 - 直接调用 API 到另一个 micro-service(这是对 micro-service 的某种指令) 需要进行更改(创建、更新、删除)。

  3. 查询 - 直接调用 API 到另一个 micro-service(就像您获取 GUID 的示例)。 同样,有些人会说这也是一个命令。 在使用 CQRS 时,通常会结合使用 Query 作为术语。

  4. Shared Db's(大部分在线资源都会告诉你不要这样做 出于多种原因) 一般来说,这不是推荐的方法。

一般

您应该根据自己的需要使用您的系统,而不是基于像这样的固定规则 "Micro Service A should never call Micro Service B".

我给你举个例子为什么:

示例:

假设您有 "micro-service A" 和 "micro-service B"。您的 "micro-service B" 正在消耗 "micro-service A" 通过 Kafka 发布的事件。 "Micro-service B" 在使用事件时将一些相关的 "External" 数据存储在它自己的数据库中(复制它)。 这是一种常见的方法,不会在每次需要它的一些数据时调用 "micro-service A"。这很常见,例如 如果 "micro-service A" 是具有系统配置设置或类似设置的服务。

假设您遇到灾难场景,您的数据库和 "micro-service B" 中的所有数据都被破坏或损坏。 为了解决这个问题,你可以只恢复你的备份并应用应用最新的事件,让我们说最后 1 小时在哪里 您的 "micro-service B" 已关闭并解决问题(如果您的事件处理实现为幂等)。在这种情况下一切都很好。

另一方面,如果您的系统 运行 已投入生产一段时间。在某个时间点之后,你开发 "micro-service C" 并决定 将其部署到生产环境。事实证明,您需要 "micro-service A" 生成的一些数据。您需要 "micro-service C" 上的数据 作为与 "micro-service B" 类似的外部数据。你如何获得这些数据? 您消费了来自 "micro-service A" 的所有事件?在理想世界中,您会永远保留 Kafka 中的所有事件。在这种情况下你会 只需订阅事件并应用所有事件即可将您需要的所有数据保存在 "micro-service C" 中。 实际上,你需要为你的 Kafka 设置一些 Retention Period,比如 5 天。如果您的系统 运行 超过 5 天,您将无法从事件中重新创建数据。

在这种情况下,您需要使用 Command/Query 直接调用服务并填充 "micro-service C" 数据库。

这只是您需要直接调用的一种极端情况示例。

总结:

还有许多其他示例表明此方法也有效。 例如,您经常需要同步调用另一个 micro-service 并且您需要等待响应(取决于您的业务场景)。最好的方法是直接用 Command/Query.

调用另一个 micro-service