Microservices(微服务架构)和DDD(领域驱动设计)是时下最炙手可热的两个技术词汇。在最近两年的咨询工作中总是会被不同的团队和角色询问,由此也促使我思考为什么这两个技术词汇被这么深入人心的绑定,它们之间的关系是什么呢?
服务于更高的业务响应力
首先从两个词汇的发明来看它们是没有因果关系的。DDD是Eric Evans于2003年出版的书名,同时也是这个架构设计方法名的起源。DDD的想法是让我们的软件实现和一个演进的架构模型保持一致,而这个演进的模型来自于我们的业务需求。这种演进式设计方法在当时看来还是比较挑战的,更为流行的解决架构设计复杂度的方法是分层:比如数据架构、服务架构、中间件架构等。MVC在互联网应用开发领域也基本成为了标配。
时间很快过了10年,Martin Fowler和ThoughtWorks英国架构师James Lewis坐下来一起分析了好几个能够持续演进的大型复杂系统,总结出了9大核心特质,然后用Microservices来定义了拥有这些特质的架构。之后由于Google、Netflix、Amazon等一系列明星企业都对号入座,Microservices开始风靡整个软件业。这时候很多人会问微服务架构是怎么设计出来的,业界人士会说DDD是一个好方法,其中也包括微服务定义者Martin Fowler,毕竟DDD原书的序是他给著的;)于是乎DDD开始在被定义10年后火了。
从我个人角度来看,如果真的需要找到因果关系的话,最根本的驱动力来自于科技时代对软件系统(数字化)响应力要求的不断提升,而系统的复杂度却随着业务的多元化而与日俱增。如何驾驭这样的高复杂度成了每个企业必须面对的挑战,以至于业界开始把这种模型总结为响应力企业(Responsive Enterprise),而模型中总结的大部分原则都是为了更好的适应环境不确定性带来的高复杂度。
从业务视角分离复杂度
每个人能够认知的复杂度都是有限的,在面对高复杂度的时候我们会做关注点分离,这是一个最基本的哲学原则。显然在针对复杂业务场景进行建模时,我们也会应用此原则。这个时候去分离关注点一般可以从两个维度出发:
- 技术维度分离,类似MVC这样的分层思想是我们广泛接受的。
- 业务维度分离,根据不同的业态划分系统,比如按售前、销售、售后划分。
以上两个维度没有孰优孰劣之分,在处理复杂问题的时候一定都会用上,但为了能够高效响应业务的变化,微服务的架构更强调业务维度的关注点分离来应对高复杂度。这是显著区别于传统SOA架构的特质之一,比如诞生于传统SOA时代的ESB(工业服务总线)就是一个典型的技术关注点分离出来的中间件。随着业务的变化,我们也看到ESB成为了一个架构上的反模式,即大量的业务规则和流程被封装在了ESB里,让ESB成为了不可驾驭的复杂度之源,以至于破坏了SOA架构之前承诺的各种优势。当然Microservices架构并非是新一代SOA架构这么简单,已经有不少文章在讨论这个话题,本文就不在展开了。
所以从本质上作为一种架构设计方法的DDD和作为一种架构风格的Microservices都是为着追求高响应力目标而从业务视角去分离复杂度的手段。
如果这个时代你还觉得自己的架构不需要这种响应力,我建议你问问身边维护3年以上系统的朋友或同事们,他们会告诉你这是怎样的一种痛苦。实际上很多企业对这种响应力的追求已经很“疯狂”了,这也是微服务的两位定义者可能都始料未及的。
他们在定义文章中带着很强警告语气让大家慎用,但在这个科技时代,微服务架构实施的可能风险对比高响应力在未来可能带来的市场机会几乎可以忽略不计。一个Netflix的成功就足以让大部分企业毫不犹豫的选择微服务作为自身的架构风格。
业务和技术渐进统一的架构设计
如果Microservices和DDD在目标上达成了上文的统一,那么在具体做法上和以前有什么不同呢?
为了解释清楚这个问题让我们极简化架构设计为以下三个层面工作:
- 业务架构:根据业务需求设计业务模块及交互关系。
- 系统架构:根据业务需求设计系统和子系统的模块。
- 技术架构:根据业务需求决定采用的技术及框架。
显然这三者在具体一个架构设计活动中应该是有先后顺序的,但并非一定是孰先孰后,比如一个简单的web应用,很多人会说MVC是标配了(首先确定了系统架构),或者有人说用RoR快(首先确定了技术架构)。在给定的业务场景里,也许这样的顺序是合理的。
架构设计工作分层及传统意义上的负责人
这个时候咱们增加复杂业务需求和快速市场变化这两个环境变量,这个顺序就变得很有意思了。于是我们听到不少走出初创期的互联网服务平台开始“重写”他们的系统(从PHP到Java),很多文章开始反思MVC带来的僵化(臃肿的展现层)。经历了这样变迁的架构师们都会感同身受的出来为DDD站台,其原因就是“跳过”(或“后补”)业务架构显然表明设计出来的架构关注点并不在业务的响应力上,因为业务的可能变化点并没有被分析出来指导系统和技术架构的设计。
DDD的核心诉求就是能够让业务架构和系统架构形成绑定关系,从而当我们去响应业务变化调整业务架构时,系统架构的改变是随之自发的。
这个变化的结果有两个:
- 业务架构的梳理和系统架构的梳理是同步渐进的,其结果是划分出的业务上下文和系统模块结构是绑定的。
- 技术架构是解耦的,可以根据划分出来的业务上下文的系统架构选择最合适的实现技术。
第一点显然也是我们产生微服务划分所必须遵循的,因为微服务追求的是业务层面的复用,所以设计出来的系统必须是跟业务一致的。第二点更是微服务架构的特质:“去中心化”的治理技术和数据管理。 作为架构设计的方法,DDD的各种实践,包括最近流行的Event Storming(事件风暴)实际上都是促进业务和系统架构梳理的渐进式认知。
在一次DDD工作坊中,一位同事给出了“你们连业务故事都讲不清楚,还有必要继续做架构设计吗?”这样的经典评论。而DDD的整个方法也没有涉及具体的技术架构实现,这个选型的权利很多时候被“下放”给了真正的开发团队。
值得一提的是采用DDD这种架构设计方法并不一定就产生Mircoservices这种架构风格,往往会推荐用大颗粒度的服务来包含业务分析过程中发现的不确定点,以避免拆分后变化过度频繁带来的双向修改成本。
跨职能协作的架构设计
业务和系统的渐进认知改变了很多之前的架构工作模式,在采用DDD的过程中,很容易感受到业务专家的重要性。而如果还有人寄希望让业务能够一次性给架构师讲清楚需求,那我建议抱有这样希望的同学去亲身参加一次自己不熟悉业务领域的架构设计讨论。你会很容易得出结论“原来业务也不懂他要什么”。当然业务人员听说要参加某种(软件)架构设计方法时心里也一定是抵触的。
DDD成功运用的基础就是创造让业务和系统这两种不同认知模型逐步统一的环境。
业务架构和系统架构设计
所以“不幸”的是如果你不能建立一个跨业务和技术的新型架构设计小组,你的DDD实践就没有成功的基础,继而采用微服务架构可能就会是一场灾难。幸运的是这种跨职能组织结构已经是前文中“采用”微服务架构企业(如Amazon)的标配,你不必再论证这件事情的可实施性。剩下的关键就是如何能够让不同背景的人们协作起来。这也是大家可以看到DDD领域的下一个热点,类似Event Storming这样的模式化协作工作坊会更多的出现在大家的视线里。
永无终止的DDD和演进的Microservices
DDD是容易上瘾的,当大家发现原来通过这个建模过程业务专家更了解服务划分(系统模块),架构设计更懂业务需求,这种协作会成为常态。在这个tech@core的时代,这样的融合将成为企业的核心竞争力。
当然刚开始采用DDD方法的时候,请不要认为每个系统搞一次所谓的DDD工作坊就能够找到最佳的服务划分了。业务的变化是持续的,而每次业务架构变化必然牵动系统架构的变化。良好的领域架构绑定了业务和系统,让双方人员能够用统一语言交流,这件事情建立不易,而持续运作更难。
成功的DDD方法运用是贯穿系统的整个生命周期的,这个过程中业务和技术的协作是持续发生的。
Microservices的最后一个特质:“演进式”设计 – 也明确了设计是一种持续的活动。DDD提供了一种符合这个微服务特质的工作方法,让演进能够落地。值得一提的是就笔者最近的经验,这个演进过程中最难认知到变化的就是DDD里最显而易见的“统一语言”。当大家形成了一个业务概念-“客户”后,少有团队能够持续审视这个“客户”是否随着市场的变化而发生了含义的变迁。
对比传统的SOA,微服务的拆分也是动态的,禚娴静在自己的文章中描述一个系统采用微服务架构历程中服务拆分的演变。这里不会有一个ESB来以不变应万变,这种幻想在过去的10年里已经被数次打脸。DDD的好处是让业务和技术人员都能够在合作中理解这种变化,而不至于陷入业务人员抱怨技术架构不知所谓,技术人员觉得业务人员朝三暮四的尴尬。
你需要成为那个高个子!
Martin Fowler在Microservies的定义文章中画了下面的图,评论“你必须有那个高度”来隐喻微服务实施的能力要求。就架构建模方面来说我认为DDD应该是一个团队必须去掌握的,包括这个团队的业务人员和产品设计人员。
微服务前置条件示意
很有意思的是目前Service Design也是全球用户体验设计领域的一个热门话题,从用户视角出发去设计整个服务链条。比如时下热门的共享单车,一个成功的服务设计应该是从用户开始有用车需求触发到最后完成骑行缴费离开,而不仅仅是去设计一辆能够互联网解锁的自行车。
我们可以找到很多Service Deisgn和DDD在原则上的相似之处,比如用户中心和协同设计。借用上面的高个子说法:
在业务需求认知和跨职能协作方面你一定需要成为高个子!
更多精彩洞见,请关注微信公众号:思特沃克