我希望获得一些关于在微服务中处理数据依赖关系的不同解决方案的反馈。
考虑以下服务:
简要说明一下,这里有银行服务和帐户服务。帐户服务保留帐户,并始终使用bankId将其连接到银行。
难题是如何处理和验证此关系以及bankId以及每个决策附带的利弊。
选项1:
完全忽略验证。如果给定的BankId是现有ID,则针对帐户的POST / PATCH将永远不会验证。
优点
缺点
反射
服务完全脱钩,这将使性能,运行时间和复杂性受益。当跨服务关系“中断”时,所有阅读器和应用程序都必须“具有反应性”并能够处理。
选项2:
始终使用同步REST调用进行验证。如果BankId不存在,或者无论如何BankService无法响应或损坏,针对帐户的POST / PATCH将失败。
优点
缺点
如果BankService关闭,那么
反射
服务是紧密依赖的,这确实很糟糕,这更像是“旧方法”,通常我觉得这是错误的方法。在这种情况下,合并服务的情况甚至更糟,如果您开始通过合并来解决问题,那么您可能会继续这样做,并很快会获得大量服务,而您却无法遵循整个微服务原则。当然,读取仍然有效,但这是一个牵强附会的借口。
选项3:
在AccountService中保留BankEntity的只读副本。 AccountService通过事件总线保持更新。在POST / PATCH上对此进行验证。
优点
缺点
反射
这是最复杂的方法,读者不需要处理断开的关系,并且可以解决性能/正常运行时间问题,但是,您必须处理以下事实:银行的只读副本可能尚未更新,然后尝试稍后再试。将其与选项1进行比较意味着您仍然必须以某种方式处理它,并且由于这将更加复杂,所以我认为这不是最有利的选择。
结束想法
可以很好实现的总体目标是,服务之间不能同步进行对话,并且数据完整性尽可能好。
但是,在微服务体系结构中,我给人的印象是,关系完整性可能只是您无法接受的那种方式之一。
我们的决定倾向于选择1,实际上只是忽略它,而在任何需要使用它的地方,您都必须期望并处理它可能是不正确的。这似乎是最“微服务”的解决方案,服务之间并不真正了解彼此,唯一的服务是需要执行跨服务操作的应用程序和报告服务。
任何服务都必须承担全部责任,以确保它们在任何给定的时间都拥有自己能够充分发挥作用所需的所有数据。假设出于争论的缘故,无论出于何种原因,AccountEntity都需要一个位置才能成为可用且完整的域实体,您不能指望依赖BankId,而必须将Location存储在AccountEntity上,并且如果它发生更改,您会得到一个事件,你可以更新它。
TL; DR
您对此有何经验,看法和想法?你会怎么做?您会选择哪种策略?
最佳答案
首先,您选择的选项将取决于您的业务需求。
**首先,我将允许在未经验证的情况下创建帐户,该帐户的初始状态为CREATED
**现在,在AccountService中创建一个ProcessManager来监听AccountCreated事件,并异步地使用Bank Service对其进行验证,以
检查银行编号是否有效,如果是,则将帐户状态更新为
VERIFIED,或者如果银行ID无效,请将状态更新为INVALID BANK ID
并采取适当的行动
现在实际上所有方法都是有效的,可能取决于您的关键业务需求。有时即使需要创建依赖项也需要实时验证
关于architecture - 微服务关系/依赖策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49252691/