【问题标题】:Microservice Data Duplication vs Single Responsibility微服务数据复制与单一职责
【发布时间】:2021-06-21 22:02:06
【问题描述】:

我是微服务新手,正在尝试将大型单体应用程序分解为微服务。在确定微服务的范围时,我无法决定是否应该在服务之间进行数据复制,或者通过将所有需要相同数据的服务合并到一个服务中来忽略 SRP。以下是场景。

我有一项服务,它收到客户的订单,说用这些零件和功能建造一辆汽车。现在我还有其他 2 个功能,它们使用部件和功能来获得一些运行时价值,比如说;

如果订单包含part A和Feature A,则执行X操作。由于这些功能中的每一个都有各自的 UI 用于配置和运行时引擎以派生输出,并且大部分时间更改只出现在这些各自的功能块中,因此我考虑创建单独的微服务。

创建单独的微服务需要复制数据(部件和功能)。另一种选择是,这些服务中的每一个都使用相同的数据,将它们全部归为 1,但是我再次创建了一个大型服务,如果出现故障将停止所有 3 个功能并且违反 SRP。另一种选择可能是当其他 2 个服务需要数据时进行调用并从 Order Service 获取数据,但这会使其高度依赖并通过网络为每个操作获取数据。

任何人都可以建议在这种情况下做什么是理想的。

【问题讨论】:

    标签: microservices


    【解决方案1】:

    首先,您提到您正在尝试将单体应用程序转换为微服务。您可以基于领域数据创建/提供微服务,我们可以称之为领域驱动架构。

    假设您具有客户数据、客户订单、客户订单处理和客户付款的业务功能。目前,它是单体应用程序的一部分。因此,您可以分别为客户域、订单域、订单处理域和支付域等每个功能创建子域。每个域包含多个微服务,具体取决于业务需求。

    例如,您可以查看亚马逊网站,在个人/客户数据中,您会看到客户姓名、电话号码、地址、账单账户信息、送货地址类型(办公室/家庭)。在这种情况下,在客户域下,将需要 3 个微服务(这完全取决于您的域设计)。一个用于客户(处理客户名称、电话号码、计费帐户 ID 的引用、地址 ID 的引用),第二个用于计费帐户(计费帐号、计费帐户信息、如果客户 ID 的引用),第三个用于地址数据(客户办公室地址,首选地址)。并且对于每个微服务,都会有一个专用的数据库/存储桶,只有该微服务可以更改/添加数据。如果任何其他微服务想要添加/更新/获取数据,则需要通过网络调用该微服务 HTTP 端点来获取。

    更新其他微服务中的数据::

    现在谈到您关于数据重复的问题,让我们考虑上面的示例。 如果客户微服务出于某种目的想要存储/缓存计费帐户数据,则该微服务可以将该数据存储在数据库中但是客户微服务需要再次确保计费帐户的当前数据始终是真实的,并且不是旧的。对于这个客户,微服务需要在计费账户数据有更新时监听事件,因此计费账户中的旧数据被清除,客户微服务始终拥有最新的计费数据。

    您可以在此处阅读有关事件驱动架构的信息。

    https://en.wikipedia.org/wiki/Event-driven_architecture#:~:text=Event%2Ddriven%20architecture%20(EDA),sale%22%20to%20%22sold%22.

    您可以在以下有关领域驱动设计的链接中阅读更多相关信息。

    https://www.thoughtworks.com/insights/blog/domain-driven-design-services-architecture

    https://en.wikipedia.org/wiki/Domain-driven_design

    【讨论】:

      【解决方案2】:

      微服务应该使用发布者/订阅者模型和主题通过事件进行通信。请参阅tri-lateral 设计模式。在发布/订阅系统中,生产者将事件写入主题,代理将其提供给每个订阅者,也就是微服务。这是事件、一个生产者和多个消费者的优势之一。

      订单 A 有一个 BOM,表示订单代表的零件和特征。下订单后,其他服务需要该信息,例如功能/部件微服务和 UI 组件及其各自的数据存储。例如,定义两个主题 part-ordered 和 features-ordered。

      订单微服务分别写入部件和特性主题。功能、部件和 UX 微服务读取这些事件并根据这些事件采取行动。

      您需要对您的记录系统做出选择。您可以在发布事件之前写入订单数据库,或者让发布/订阅它。在您的示例中,听起来您在谈论三个不同的表;订单、零件和事件。这将清理分解为您描述的微服务,每个微服务都在其中维护其负责的数据。我倾向于只使用 pub/sub 作为您的审计线索。

      如果您使用 Go 编写,我们有最常见设计模式的蓝图。

      【讨论】:

        【解决方案3】:

        有多种方法可以将应用程序分解为服务。

        1.Decompose by business capability

        2.Decompose by subdomain

        还有多种数据管理方式

        1. SAGA
        2. API Composition
        3. Database per service

        更多详情请点击链接click

        【讨论】:

          【解决方案4】:

          这是我的免费书 :)

          如果您想创建微服务,则需要遵循微服务指南。

          现在来到现实世界 :) 真的很难满足所有微服务要求,因为数据库有自己的许可成本等,所以你可以选择实用的微服务。您可以更快地开始使用它们,并挑选对您的团队有意义的部分。

          设计领域驱动的面向设计的微服务:DDD 将问题视为领域。它将独立的问题区域描述为限界上下文,每个限界上下文都与一个微服务相关。

          在哪里划界是设计和定义微服务时的关键任务。

          DDD 模式可帮助您了解域中的复杂性、每个限界上下文的域模型、识别和定义为您的域建模的实体、值对象和聚合。您构建和细化包含在定义上下文的边界内的域模型。这在微服务的形式中是明确的。这些边界内的组件最终成为您的微服务。

          现在您可以在微服务之上创建层,并使用编排和编排构建复杂的逻辑。

          例子:

          网关客户订单应用层微服务--领域模型层微服务基础设施层

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-10-23
            • 1970-01-01
            • 1970-01-01
            • 2019-06-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多