如何实现微服务外部的约束?

时间:2019-07-31 21:44:40

标签: microservices

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

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

这些是我能想到的方法:

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

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

2 个答案:

答案 0 :(得分:1)

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

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

如果客户订单计数器为0,则可以删除客户。

答案 1 :(得分:0)

让我们从您的第三种方法开始:在微服务世界中,这是行不通的,因为在某些服务之间始终会有这些约束。而且,如果您想以这种方式解决所有问题,那么您将获得Monolith-这就是您的微服务故事的结尾。

第一种方法和第二种方法都具有相同的“问题” :这些是异步操作,可能会返回假肯定(或假否定)结果:可以针对以下情况提出api请求: delete customercreate order(或delete order)同时出现。

尽管这种可以发生:

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

  • 第二种方法也是如此:这些服务之间的消息传递是异步的。尽管客户服务部门可能知道0订单,并允许删除。但是同时,订单服务会为此客户创建一个新订单。在客户已被删除之后,OrderCreated消息将进入客户服务。

  • 如果您尝试以其他方式执行此操作,则会遇到相同的情况:您的订单服务可以监听CustomerDeleted消息,然后禁止为该客户创建新订单。但同样:该消息可以到达,而数据库中仍然有该客户的订单。

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

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

该问题的答案很可能取决于您的业务规则。例如:如果订单服务收到CustomerDeleted消息,则可以简单地从此客户中删除所有订单。也许行为取决于订单的state属性:可以删除带有state = draft的所有订单,但是仍然应该照常处理和运送来自此客户的所有其他订单。