单体 Web API 到微服务设计
Monolithic Web API to microservice design
我们的应用程序中有一个单体 Web API 层,有一百个端点。我正在尝试使用 Azure Service Fabric 将其分解为微服务。
当我们将它们分解成多个服务时,我们可能最终会得到重复的代码。
示例:假设我们有一个帐户服务来创建一个帐户。并且有一种支付服务可以将支付应用于交易。
在这种情况下,两种服务都需要客户 class/domain。帐户服务可能需要一个详尽的客户,提供完整的详细信息,但付款可能需要一个轻量级的客户。
问题是我们是否需要像这样复制几个域实体和其他层?这不会造成更多维护问题吗?
如果我们不这样做,我们最终会复制代码并创建不同的服务,一个相同的整体服务就是现有的 Web API。
对此有什么想法吗?
第二,我们今天有一些案例提到交易。如果我们把它们分开,有什么好的设计可以记录失败和回滚而不用过多地维护事务?
将单体分解为具有适合您领域的适当边界的适当微服务当然更像是一门艺术而不是一门科学。承担此类任务的先决条件是对您的领域及其内部交互有透彻的了解,您不会一次就做对。 Evans 在他关于领域驱动设计的书中提出的观点之一是,对于任何足够复杂的领域,领域模型不断发展,因为您对该领域的理解不断发展;明天你会比今天更好地理解它。也就是说,当您了解 "good enough" 并愿意 adapt/evolve 您的模型时,不要害怕开始。
我不知道你的域,但在我看来你需要先弄清楚 bounded context Customer
主要属于哪个域。是的,您希望最大限度地减少域逻辑的重复,尽管它可能无法完全、整齐地适合单个服务,但您可以让一个服务承担访问、持久化、操作、验证和确保完整性的主要责任a 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
除了单个 API 调用外,如何 更新 Customer
的账单地址一无所知; Customer
微服务中包含需要作为该操作的一部分发生的任何域逻辑、验证、域事件的触发等。
关于您的第二个问题:原子事务在分布式架构中确实变得更加 complex/difficult。阅读 Saga 模式:https://blog.couchbase.com/saga-pattern-implement-business-transactions-using-microservices-part/。此外,Jimmy Bogard 目前正在创建一个名为
Life Beyond Distributed Transactions: An Apostate's Implementation 这可能会提供一些很好的见解。
希望对您有所帮助!
我们的应用程序中有一个单体 Web API 层,有一百个端点。我正在尝试使用 Azure Service Fabric 将其分解为微服务。 当我们将它们分解成多个服务时,我们可能最终会得到重复的代码。
示例:假设我们有一个帐户服务来创建一个帐户。并且有一种支付服务可以将支付应用于交易。 在这种情况下,两种服务都需要客户 class/domain。帐户服务可能需要一个详尽的客户,提供完整的详细信息,但付款可能需要一个轻量级的客户。
问题是我们是否需要像这样复制几个域实体和其他层?这不会造成更多维护问题吗?
如果我们不这样做,我们最终会复制代码并创建不同的服务,一个相同的整体服务就是现有的 Web API。
对此有什么想法吗?
第二,我们今天有一些案例提到交易。如果我们把它们分开,有什么好的设计可以记录失败和回滚而不用过多地维护事务?
将单体分解为具有适合您领域的适当边界的适当微服务当然更像是一门艺术而不是一门科学。承担此类任务的先决条件是对您的领域及其内部交互有透彻的了解,您不会一次就做对。 Evans 在他关于领域驱动设计的书中提出的观点之一是,对于任何足够复杂的领域,领域模型不断发展,因为您对该领域的理解不断发展;明天你会比今天更好地理解它。也就是说,当您了解 "good enough" 并愿意 adapt/evolve 您的模型时,不要害怕开始。
我不知道你的域,但在我看来你需要先弄清楚 bounded context Customer
主要属于哪个域。是的,您希望最大限度地减少域逻辑的重复,尽管它可能无法完全、整齐地适合单个服务,但您可以让一个服务承担访问、持久化、操作、验证和确保完整性的主要责任a 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
除了单个 API 调用外,如何 更新 Customer
的账单地址一无所知; Customer
微服务中包含需要作为该操作的一部分发生的任何域逻辑、验证、域事件的触发等。
关于您的第二个问题:原子事务在分布式架构中确实变得更加 complex/difficult。阅读 Saga 模式:https://blog.couchbase.com/saga-pattern-implement-business-transactions-using-microservices-part/。此外,Jimmy Bogard 目前正在创建一个名为 Life Beyond Distributed Transactions: An Apostate's Implementation 这可能会提供一些很好的见解。
希望对您有所帮助!