【问题标题】:Monolithic Web API to microservice design单片 Web API 到微服务设计
【发布时间】:2019-01-21 09:22:15
【问题描述】:

我们的应用程序中有一个单一的 Web API 层,有一百个端点。我正在尝试使用 Azure Service Fabric 将其分解为微服务。 当我们将它们分解为多个服务时,我们最终可能会出现重复的代码。

示例:假设我们有一个帐户服务来创建一个帐户。并且有一项支付服务可以将付款应用于交易。 在这种情况下,两个服务都需要 Customer 类/域。帐户服务可能需要一个详尽的客户提供完整的详细信息,但付款可能需要一个轻量级的客户。

问题是我们是否需要像这样复制几个域实体和其他层?这不会造成更多的维护问题吗?

如果我们不这样做,我们最终会复制代码并创建不同的服务,一个单一的服务就是现有的 Web API。

对此有什么想法吗?

第二,我们有一些今天提到交易的案例。如果我们将它们分开,是否有任何好的设计来记录失败和回滚,而无需过多地尝试维护事务?

【问题讨论】:

    标签: microservices azure-service-fabric


    【解决方案1】:

    将单体架构分解为适当的微服务,并为您的领域提供适当的边界,这肯定是一门艺术,而不是一门科学。承担此类任务的先决条件是彻底了解您的领域和其中的交互,而且您不会第一次就做好。埃文斯在他的领域驱动设计一书中提出的观点之一是,对于任何足够复杂的领域,领域模型都会不断发展,因为你对领域的理解也在不断发展。明天你会比今天更了解它。也就是说,当您的理解“足够好”并愿意适应/发展您的模型时,不要害怕开始。

    我不知道您的域,但在我看来,您需要先弄清楚bounded context Customer 主要属于哪个域。是的,您希望最大限度地减少域逻辑的重复,尽管它可能无法完全和整齐地融入单个服务,但在某种程度上,您让一个服务主要负责访问、持久化、操作、验证和确保其完整性Customer,你会过得更好。

    从你的问题中,我看到了两种可能性:

    • Account Services 有界上下文是Customer 中的主要利益相关者,Customer 与其他Account Services 实体和服务有着重要的联系。孤立地围绕Customer 划清界限是很困难的。在这种情况下,Customer 属于Account Services 有界上下文。
    • Customer 是一个足够独立的概念,值得拥有自己的微服务。 Customer 可以独立存在。在这种情况下,Customer 属于它自己的有界上下文。

    在任何一种情况下,都应特别注意确保Customer 特定的域逻辑集中在强边界后面的Customer 微服务中。其他服务可能使用Customer,或者可能是轻量级(甚至是只读的)CustomerView,但它们的交互应该尽可能通过Customer 服务。

    在您的问题中,您指出Payments 有界上下文需要访问Customer,但它可能只需要一个轻量级版本。它应该与Customer 服务通信以获取该轻量级对象。例如,如果在付款处理期间您需要更新Customer 的帐单地址,Payments 应该调用Customer 微服务,告诉它更新其帐单地址。 Payments 不需要知道任何关于如何更新Customer 的帐单地址而不是单个 API 调用;任何需要作为该操作的一部分发生的域逻辑、验证、触发域事件等...都包含在 Customer 微服务中。

    关于您的第二个问题:在分布式架构中,原子事务确实变得更加复杂/困难。阅读一下 Saga 模式:https://blog.couchbase.com/saga-pattern-implement-business-transactions-using-microservices-part/。此外,Jimmy Bogard 目前正在撰写一个名为 Life Beyond Distributed Transactions: An Apostate's Implementation 可能会提供一些很好的见解。

    希望这会有所帮助!

    【讨论】:

    • 谢谢乔恩。如果我们让所有其他微服务与客户服务交谈以获取客户详细信息,那么如果我们在它们之间使用 http 协议(服务结构中的无状态服务),是否会影响性能。
    • 是的,这是与微服务架构的权衡之一,但如果您的服务间通信保持在您的 SF 集群中并且您没有进行到处都是大量的啤酒花。
    • 我在 SF 的解决方案中有一个类似的问题要解决。我的计划是在需要这些数据的每个服务中都有一个简单客户列表(以及其他“全球”集合以及货币汇率)的本地缓存副本。有一个独特的全局服务来管理这些客户喜欢的集合,并且可以在项目发生更改时通知所有其他缓存这些对象的服务。这样,我将避免大量的服务间调用,只是为了读取不会经常更改的数据。
    • 在我的应用程序中,客户也可以是演员服务。由于演员的状态已满,我可以获得他们的客户信息,用于基本操作。何时将其作为服务与何时将其作为演员的任何见解。我的服务是无状态的,因为我们有外部数据库,所以我打算使用演员和缓存客户信息。
    猜你喜欢
    • 2019-10-27
    • 1970-01-01
    • 2017-09-21
    • 2019-05-21
    • 2016-02-16
    • 2017-12-13
    • 1970-01-01
    • 2022-06-28
    • 2022-11-23
    相关资源
    最近更新 更多