【问题标题】:Microservices unsuitable for business domain?微服务不适合业务领域?
【发布时间】:2023-12-03 06:19:01
【问题描述】:

业务领域有五个高级有界上下文

  • 客户
  • 应用程序
  • 文档
  • 决定
  • 瓶坯

此外,这些有界上下文具有子上下文,例如文档的排序和交付。尽管该项目由数万个类和数十个 EJB 组成,但大多数业务逻辑都驻留在关系数据库视图和触发器中,原因是:所有业务事务中都涉及大量连接、联合和约束。换句话说,有界上下文之间存在复杂的依赖关系和约束网络,这限制了状态转移。通俗地说:业务规则非常复杂。

现在,如果我要将这个单体架构拆分为每个服务微服务架构的数据库,有界上下文是建议的服务边界,我将不得不使用显式 API 调用来实现所有业务逻辑。我最终会得到数百个 API 来实现所有这些愚蠢的小业务规则。由于性能是主要因素(我们花了很多精力来优化现在的 SQL),所以这是不可能的。其次,在这个不断发展的业务规则网络中维护隔离的 API 可能是一场噩梦,因为数据库触发器实际上支持高内聚和 DRY 心态,透明地执行业务规则。

我得出的结论是微服务架构不适合这种类型的文档管理系统。我是正确的,还是从错误的角度接近这个想法?

【问题讨论】:

  • 你为什么想要转向微服务?
  • 如果您的微服务拥有自己的数据库并且您将在所有这些数据库中复制数据,那么您可以实现所需的性能。但在你的情况下,这听起来不像是一个选择。要在每个服务中实现更少的 API 方法,您可以使用 specification 开发模式。此外,您还可以使用GraphQL 之类的东西来减少传输的数据量并简化 API 接口。

标签: database domain-driven-design microservices distributed-computing soa


【解决方案1】:

首先,您不必拥有微服务架构。我真心的!如果管理层/架构师命令您这样做,但它并不能解决您遇到的任何实际问题,那么您可能适合推迟。

话虽如此,并且我不知道您的应用程序的确切要求的免责声明,将“事物”作为有界上下文是一种气味。因此,将“客户”、“应用程序”、“文档”等作为服务很可能是错误的做法。

有界上下文不应该是对特定实体的 CRUD 操作。它们应该是整个应用程序的完全独立(或尽可能独立)的“垂直”部分。最好有自己的数据库 GUI。它们还应该彼此独立运行,而不需要其他服务的输入来做出自己的决定。

这与以数据为中心的设计完全相反,表/字段和关系是核心概念。在这里,功能是核心概念。您必须按照功能拆分应用程序才能实现良好的分离。

我可以想象一个文档管理系统具有这些独立的有界上下文/服务:搜索工作流编辑等。

这是您的想法:搜索不需要来自任何其他服务的任何(同步)输入。它可能会定期收到新文档的更新,甚至是近乎实时的更新,但这并不影响它的主要功能:搜索已编入索引的文档。 GUI 也是独立的,可能类似于带有搜索框的类似 google 的页面。它可以独立提供结果,并在您单击结果时链接回到工作流编辑应用程序。

其他人将同样独立。同样,重点是以使它们独立工作的方式拆分服务。如果你没有这个,你只会让微服务变得更糟。

【讨论】:

    【解决方案2】:

    首先,上述答案是正确的,表明您需要以更好的方式分解您的微服务。

    现在,如果您关心可扩展性(微服务之间的大量 api 调用)。

    我强烈建议您验证在第一级确实需要多少约束,以及您可以以异步方式执行多少约束。我的意思是在分布式环境中,我们实际上不需要同时验证所有事物。

    有时这些东西不是直接可见的,例如:假设有两个服务订单服务和客户服务和订单服务公开一个 api,它说为客户 ID 下订单。和商家说您不能为未知客户下订单

    一个实现是来自您同步调用客户服务的订单服务 ---- 在这种情况下,客户服务下降会影响您的服务,现在让我们问一下我们真的需要这个。

    因为可能会发生这样一种情况:客户刚下订单,有人从客户服务中删除了该客户,现在我们有一个不属于客户的订单。无法保证一致性。

    在新的溶胶中。我们是说允许订单服务在不检查客户 ID 的情况下下订单并执行以下操作之一:

    使用 ProcessManager 检查客户有效性并将订单状态更新为无效,当客户被删除时,使用 ProcessManager 将订单状态更新为无效或执行业务逻辑 根本不要检查,因为下订单不算什么,当该订单处于发货过程中时,该服务无论如何都会检查客户状态

    通过这种方式,您的 API 命中率会降低并产生更好的独立服务

    【讨论】: