摘要:微服务架构看起来像DDD的一个不错的细化,进一步为你的子域 / 限界上下文隔离职责。我下一篇,会带你浏览一些可行的方法,可以用来绕过这个领域模型、DDD和微服务的潘多拉魔盒。

到底DDD带来了多大好处

有一段时间 DDD 还很新,当初 Eric Evans 首次发表他的种子工作 领域驱动设计:软件核心复杂性应对之道,书里的灵感让我们感到像找寻到了一个个治愈创伤的良药。Evans创造的是一种更好的方法用来构造复杂逻辑,因此不仅是我们的代码,甚至我们的整个应用也更容易理解,并且更少的逻辑分散和无尽无休的意大利面条代码、重复行为。

那是过去的事了,从那时起,我们用DDD获得了各种各样的成功,无论是在你的上下文地图中拆分限界上下文, 实现领域服务或者基础设施逻辑,甚至(这是对我来说最主要的)教育老开发新招数:反思并教育开发者去思考DDD,不是像我过去那样只复制粘贴代码。

这有一个简单的DDD限界上下文图(如果这与你的理解有区别,敬请原谅,DDD有些部分对于不同的实现者来说会略有不同)

一个限界上下文和用它交互的方式

限界上下文和用它交互的方式

如果你从未用别的方式工作过,那你真是万幸。那些像我一样工作在复杂的业务应用中,在没用DDD时,可以说那些故事可谓是暗无天日。如果你现在工作于像那样的一个丑陋、古板的梦魇般的应用,我对你表示同情。

一起来微服务

不久前,有个新术语席卷全球IT界。它就是“微服务”。什么是微服务?好吧,任何定义都不足以概括,来看看维基百科的说法:

微服务是一种软件开发技术 -- 一种面向服务架构(SOA)的变体架构风格,构建应用成为一组松耦合的服务集合。微服务架构中,服务是细粒度、轻量的。

这些都太泛泛了,我承认。可能下图会有帮助:

一个微服务架构及交互方式

微服务承担一个单一职责,和从属于它的一部分业务流。它们可以是整个产品的一部分,与兄弟(也可能是外部的系统)产品通过轻量的通信交互,且是松耦合关系。所以现在我的业务逻辑都是隔离为小的工作单元,每个负责它自己的职责,它们互相通信完成一项任务。

现在,在表层看起来就很漂亮了。我的产品实际已经拆解成了更小,更深思熟虑的服务,每个都补全了一部分我的产品要提供的能力,微服务们相互通信,更高效地完成任务。

微服务与DDD共舞?

在上次的初见中,你猜它们会在一起愉快的玩耍?DDD和微服务架构都是关于构建严谨的职责边界的,因此应用是分布式的,以及确保你的应用没有一个部分是超出本职的。

微服务架构看起来像DDD的一个不错的细化,进一步为你的子域 / 限界上下文隔离职责。我们本能直觉这是天作之合。理论上,DDD作为封装业务逻辑的指导思想,然后落地以松耦合,单一职责的微服务,这一切听起来像田园诗般美好。 但是,事实上那只是理论上 。

科学的巨大悲剧在于 ―― 丑陋的事实可杀死美好的假说。 -- Thomas Huxley

当我们深挖那些魔鬼细节,我们开始看到事情变味了。

微服务作为自包含的数据主

很重要一点是要记住,微服务期望成为一个自包含的实体。它负责维护的不仅有它自己的内部逻辑,还有它所有的内部数据。 这就意味着要获取和持久化数据到数据库,或者也意味着它自己的数据结构(像在DDD里的实体和聚合根)。共享微服务的数据(暴露的API后方的支撑)是一个大忌,这个大忌就是让一个限界上下文去迎合另一个限界上下文的数据库。这会导致另一个问题。

微服务作为可自部署的工作单元

尽可能,每个微服务应该是可自部署的,构建你的产品微服务的关键一点,就是任何部分可以独立于其它部分被开发和部署。如果每次我修改其中一个,我需要部署所有的三个微服务,我可能还没有对这个架构感到厌烦。而经验规律是,如果一个微服务的变更需要重新部署x个其它服务且要按顺序分别都成功, 当x越大,你的架构就越糟糕。

领域模型应该在何处容身?

我说过大问题之一就是要面对微服务架构中领域模型要在哪里容身。

传统的DDD应用,我们的领域模型是个共享资源,一个编译过的聚合或者一个依赖包,我们的限界上下文使用它贯穿应用服务,仓库和领域服务。

好了,现在我们遇到了个难题。如果我想让一个微服务可以独立于其它服务部署,我们怎么做?如何让我更新了领域模型,不让所有微服务做被动更新? 并且在DDD范式,我如何隔离我的微服务数据(包括数据模型),仍然保持我的领域模型是内聚的?

下一期...

我下一篇,会带你浏览一些可行的方法,可以用来绕过这个领域模型、DDD和微服务的潘多拉魔盒。已经有一些组织采用过以对抗这些问题,我们将看看每一个方法,以及它们的优缺点。

下回见 :)

相关文章