这是一个理论性很强的问题,主要集中在我没有完全掌握微服务中相关数据背后的设计原则以及获取相关数据的责任。
我的数据的基本要点可以举例如下(每个服务还在数据库中托管以服务命名的数据,为简单起见我将隐藏它):
我有一个 API 网关路由 /api/* 请求到他们适当的服务和处理身份验证。 我有一个物种服务,这个物种有一个 GUID PK 和一个名字。 我有一个动物园服务,动物园有一个 GUID PK 和一个名字。 我有一个动物服务,一个动物有一个 GUID PK,一个物种 FK 和一个动物园 FK 和一个名字。
必须发生以下情况:
这是我目前的实现(我认为可能有缺陷):
我有以下两个问题:
这种分解看起来像是采用关系数据库模式并将每个表分配给不同的微服务。这种分解采用了单体应用的所有耦合,并将其与微服务的所有复杂性相结合,这意味着您从两者中获得的好处都很少。
另一种分解侧重于功能:公开了哪些操作以及它们之间的关系(以及操作之间应该保持什么样的一致性/独立关系)。如果两个操作之间有很强的一致性要求,那就是这两个操作属于同一个微服务的强烈信号(这样做并不能保证一致性,但不这样做会大大增加确保一致性的工作量,而不会带来单独微服务的好处(也许还有能力说“我们拥有比我们需要的更多的微服务!”,如果这是让人满意的事情的话))。
所以假设我们有一个“将物种 S 的动物 A 添加到动物园 Z”的操作,那么问题是我们是否要保证任何后续请求对 Z 中的所有动物、S 的所有动物或特定动物 A看到该操作的结果。如果答案是肯定的,那么这四个操作可能“希望”在同一个微服务中,因此这些操作的实现将耦合在一起。如果答案是否定的,那么最终一致性与某些活性保证可能是可以接受的,在这种情况下(除非存在某些其他一致性关系)将操作放入单独的微服务中,并且像 CQRS 这样的模式是可能的。
如果使用 CQRS,提供“获取动物园中的所有动物”操作的服务可以对有哪些动物及其各自的物种有自己的看法。然后它不依赖于可用的动物/物种服务:那些正在关闭/无法与该服务交谈的人(这可能发生,因为一项服务改变了一些东西,应该注意)仅仅意味着视图已经过时了。最终,通信将重新建立并且操作将返回更新的数据。