architecture - 微服务关系/依赖策略

标签 architecture microservices

我希望获得一些关于在微服务中处理数据依赖关系的不同解决方案的反馈。

考虑以下服务:
enter image description here

简要说明一下,这里有银行服务和帐户服务。帐户服务保留帐户,并始终使用bankId将其连接到银行。

难题是如何处理和验证此关系以及bankId以及每个决策附带的利弊。

选项1:

完全忽略验证。如果给定的BankId是现有ID,则针对帐户的POST / PATCH将永远不会验证。

优点

  • 服务彼此之间并不了解,彼此之间也没有硬依赖性,如果一项服务出现故障,另一项服务也不会停止工作。 (这是一个很大的)

  • 缺点
  • 如果BankId不正确,则帐户“丢失”并且无法访问。
  • 报告服务和/或任何阅读器都必须考虑丢失或不正确的存储库,并提供其拥有的任何数据而不会崩溃。

  • 反射

    服务完全脱钩,这将使性能,运行时间和复杂性受益。当跨服务关系“中断”时,所有阅读器和应用程序都必须“具有反应性”并能够处理。

    选项2:

    始终使用同步REST调用进行验证。如果BankId不存在,或者无论如何BankService无法响应或损坏,针对帐户的POST / PATCH将失败。

    优点
  • 100%的数据完整性。
  • 读者不需要处理和期望破裂的关系。

  • 缺点
  • 服务是紧密依赖的,您可能会说它们不再是适当的微服务,并且可能是单一服务。
  • 性能对
  • 产生了负面影响
    如果BankService关闭,那么
  • AccountService POST / PATCH将不起作用,GET仍将起作用。

  • 反射

    服务是紧密依赖的,这确实很糟糕,这更像是“旧方法”,通常我觉得这是错误的方法。在这种情况下,合并服务的情况甚至更糟,如果您开始通过合并来解决问题,那么您可能会继续这样做,并很快会获得大量服务,而您却无法遵循整个微服务原则。当然,读取仍然有效,但这是一个牵强附会的借口。

    选项3:

    在AccountService中保留BankEntity的只读副本。 AccountService通过事件总线保持更新。在POST / PATCH上对此进行验证。

    优点
  • 100%的数据完整性。
  • 读者不需要处理和期望破裂的关系。
  • 没有可衡量的负面性能影响

  • 缺点
  • 复杂度增加
  • 由于事件的异步性质,我们不能假定Bank的只读副本已100%更新。创建BankEntity之后,快速连续地对帐户执行POST / PATCH可能会失败。
  • AccountService获得了更多关于其他服务的知识,即使它是一个松散的依赖项

  • 反射

    这是最复杂的方法,读者不需要处理断开的关系,并且可以解决性能/正常运行时间问题,但是,您必须处理以下事实:银行的只读副本可能尚未更新,然后尝试稍后再试。将其与选项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/

    相关文章:

    sql-server - SQL Server 中数据库数量的实际限制?

    kubernetes - 我可以用更智能的 nginx 配置替换 AKS k8s 内的微服务吗?

    node.js - 使用Nginx作为微服务API网关

    javascript - 如何保证数据库数据始终准确反射(reflect)在网页中?

    microservices - nestjs 微服务 - 有一个 clientProxy 将消息发布到任何微服务

    rest - 微服务、REST、事件源和数据一致性

    java - 适配器图案和包装

    xcode - 框架包含不受支持的架构 Xcode 8

    scala - Scala中基于组件的实体系统

    c# - 实现我自己的交易提供者的最佳选择