【问题标题】:How to implement constraints that are external to a microservice?如何实现微服务外部的约束?
【发布时间】:2019-07-31 21:44:40
【问题描述】:

假设我们有两个微服务,Customers 和 Orders,它们之间没有依赖关系,即它们不互相调用,也不知道彼此。但是,每个订单都通过客户 ID 引用客户。换句话说,一个客户可能有零个或多个订单,而一个订单恰好属于一个客户。

就示例而言,删除客户完全没问题除非有属于该客户的订单。如果一个或多个订单引用了该客户,那么对客户实施约束以防止删除该客户的最合适方法是什么?类似于关系数据库中的参照完整性。

这些是我能想到的方法:

  1. 让客户询问订单是否给定客户有任何订单,例如通过 API 调用。
  2. 让客户跟踪分配给每个客户的订单,例如通过让每个客户记录维护一个订单 ID 列表。
  3. 将客户和订单合并到一个微服务中并在内部进行管理。

我不确定哪种方法最适合微服务上下文中的给定示例。我可以看到所有三种方法的优缺点,但我不会在这里列出它们,因为我想听听其他人对这个问题的看法,包括上面未列出的方法。谢谢。

【问题讨论】:

    标签: microservices


    【解决方案1】:

    如果您要通过事件解耦,则第二种方法可能会有所帮助,或者跟踪 id 列表或仅告诉为此类客户存储多少订单的计数器。

    在订单微服务上,当客户(或任何其他感兴趣的微服务)将捕获创建/删除时,您将发出一个事件,客户将负责更新订单 ID 列表(或增加/减少计数器)。

    如果客户订单计数器为 0,那么您可以删除该客户。

    【讨论】:

    • 确实,就微服务独立性而言,这似乎是最好的方法。唯一让我夜不能寐的问题是数据不一致。如果客户以某种方式无法接收或处理事件,或者订单无法发送事件,那么客户数据就会变得不一致。当您只有一个这样的地方可以观看时,建立机制来检测和修复不一致可能并不难,但如果您必须观看许多其他类似的地方,则可能变得不切实际。
    • 是的,总要付出代价。像kafka 这样的经纪人可能会帮助您实现这样的目标,但是当您引入最终一致性时,您必须特别注意不要丢失任何事件(或者不要处理多次......)
    • 同意。在我看来,这甚至不是最终一致性的问题,而是一个永久不一致的问题,以及如何在不影响生产数据的情况下处理它。
    • 顺便说一下,我知道了一个非常有趣的项目,可以在这个意义上提供帮助:Debezium。如果您仍然对该主题感兴趣,请查看。
    【解决方案2】:

    让我们从第三种方法开始:这在微服务世界中是行不通的,因为在某些服务之间总是会有这些限制。如果你想以这种方式解决所有这些问题,你最终会得到一个单体应用——这就是你的微服务故事的结尾。

    第一种和第二种方法都有相同的“问题”:这些是异步操作,可能会返回误报(或误报)结果:可能会发出 api 请求delete customercreate order(或 delete order)同时进行。

    虽然这可能发生:

    • 对于您的第一种方法:客户服务询问订单服务是否有此客户的任何订单。订单服务返回0。同时订单服务在另一个线程中为该客户创建一个新订单。因此,您最终得到了一个已删除的客户,但仍然创建了一个订单。

    • 这同样适用于您的第二种方法:这些服务之间的消息传递是异步的。尽管客户服务可能知道0 订单,并允许删除。但与此同时,订单服务会为此客户创建一个新订单。在客户已被删除后,OrderCreated 消息将发送至客户服务。

    • 如果您尝试以相反的方式执行此操作,您最终会遇到相同的情况:您的订单服务可以侦听CustomerDeleted 消息,然后不允许为该客户创建新订单。但同样:当数据库中仍有此客户的订单时,此消息可以到达。

    当然,这不太可能发生,但它仍然是可能的,并且您无法在没有事务的异步微服务世界中阻止它(当然您希望避免)。

    你最好问问自己:系统应该如何处理相应客户已被删除的订单?

    这个问题的答案很可能取决于您的业务规则。例如:如果订单服务收到CustomerDeleted 消息,则可以简单地删除该客户的所有订单。或者,该行为可能取决于订单的 state 属性:可以删除带有 state = draft 的所有订单,但该客户的所有其他订单仍应照常处理和发货。

    【讨论】:

      猜你喜欢
      • 2020-12-30
      • 2015-05-17
      • 2017-09-14
      • 1970-01-01
      • 1970-01-01
      • 2011-04-09
      • 2021-11-20
      • 2023-03-09
      • 2020-09-20
      相关资源
      最近更新 更多