00前情回顾
说是前情回顾,由于我许久不曾更新此系列文章,在这新旧之交的年初,真可以说有两年这么漫长了。虽然是我的忙导致了文章更新的荒废,但归根结底,其实还是我的惫懒在作怪。人的心弦总不能一直崩着,忙活了一年,总要适当放飞一下自己,到了春节,怎么也得放松一下吧。于是,更新文章的日程就一推再推,即使有读者不断催更,我也拖着,装着没听见,不理睬。
闲话休提,上一篇文章《识别限界上下文的工作坊演练》简单点评了几位读者提交的作业,指出了在识别限界上下文时容易犯的错误,并总结了限界上下文的本质特征与验证原则。文中内容讨论的都是业务纬度对限界上下文边界的影响。
虽说业务纬度是影响和识别限界上下文的最关键因素,但影响限界上下文边界的自然不只限于此,我们还需要考虑团队纬度和技术纬度。
01团队纬度
根据康威定律,软件系统的架构应与开发该软件系统的团队结构保持一致,如此才能保证高效的沟通,并降低沟通的成本。
虽说康威定律规定了团队与限界上下文之间的关系,然而在真正开发,哪有如此理想如意呢?因而我将二者关系总结为如下图所示的三种情形:
在我的《解构领域驱动设计》一书中详细介绍了何谓“领域特性团队”,这里不再赘述,但它确实是与领域驱动开发相匹配的团队组成结构。
上图可知,理想的映射关系是一对一,即一个限界上下文对应一个团队。由于限界上下文的边界首先取决于业务,则有可能出现个别限界上下文的工作内容较少,如果完全保持一对一的映射关系,可能导致团队的工作分配不均匀。如此,就可以调整为第二种情况,即一个领域特性团队负责开发多个限界上下文。
同理,由业务决定边界的限界上下文也可能非常大,一个满足2PTS(两个Pizzas)规模大领域特性团队无法完成这样复杂的限界上下文,那么,是否可以让多个领域特性团队负责一个大的限界上下文呢?答案是不能!因为这一做法会随着时间推移,由于跨团队交流成本的增加,导致限界上下文的开发出现问题。与其被动地受到多团队交流边界的影响,不如主动出击,根据团队边界对一个相对庞大的限界上下文进行调整。这就是团队纬度对限界上下文边界的影响。
以我们识别的技术部落为例,根据语义相关性和功能相关性可以识别出直播上下文,从业务角度看,它没有继续细分的必要。但要完成直播上下文的所有功能,可能需要一个超大的团队。我曾经为一家音乐媒体公司提供咨询服务,就我了解所知,该公司的直播平台团队规模达到两百多人,怎么可能让他们都工作在一个限界上下文?这时,就应该对直播上下文进行分解。
上一篇文章《识别限界上下文的工作坊演练》确实提到一个原则,即“奥卡姆剃刀原则”,解释为“若无必要勿增实体”,现在,团队规模就是分解的足够理由了。
02技术纬度
技术纬度对限界上下文边界的影响,指的是系统的质量属性需求对限界上下文边界提出的要求,很多时候,也可以等同于是进一步确定限界上下文为微服务的依据。
这里需要先明确限界上下文与微服务的关系。二者之间的关系并无定论,毕竟Eric Evans在提出DDD时,并无微服务一说。不可否认,在微服务大行其道之时,社区如考古一般发现了DDD这套方法,借用了限界上下文这一概念作为识别微服务的依据。由此可以得出结论:如果选择了DDD帮助团队设计微服务,必然是限界上下文在先,微服务在后。
如此,仍不足以确定二者的关系。
个人认为,由于限界上下文仅限于逻辑边界,即使划分不合理,要调整起来仍然相对容易,微服务则不然,确定微服务边界时需要慎之又慎。如果没有划分微服务的绝对理由,我不建议贸然作出物理切分,而以保持限界上下文的边界为底线,只要限界上下文遵循了菱形对称架构,未来要演进为微服务,并不困难。此时的限界上下文更像是从单体迈向微服务的“中转站”,做到了“进可攻退可守”。
为了便于落地实践,我倾向于微服务的边界应大于或等于限界上下文的边界,这样定义的微服务,其实并不“微”,而是形成大小并不均衡的多个微服务。有的微服务就是一个限界上下文,有的微服务则可能包含多个限界上下文。
之所以允许这种不“微”的微服务存在,出于我的谨慎心理,不要急着让每个限界上下文都微服务化,而是考虑先定义一个规模相对大的“微服务”,其内部由多个限界上下文构成,直到有了让某个限界上下文成为微服务的充分理由,再考虑将该限界上下文拆分出来,演进为微服务。
成为微服务的充分理由,大致可以总结为:
- 资源独占性:如果需要为当前限界上下文分配单独的运行资源,则将其设计为微服务
- 可伸缩性:为满足高并发、高性能、低延迟等质量属性,需要将当前限界上下文的资源进行单独伸缩,则将其设计为微服务
- 安全性:若当前限界上下文的业务与数据需要单独的安全级别保障,则将其设计为微服务
- 独立技术栈:若当前限界上下文运行的平台、开发语言等技术栈选择完全不同,则将其设计为微服务
- 代码库版本:若当前限界上下文的版本更新周期具有独立性,则将其设计为微服务
至于技术因素中的设计要素:复用和变化,只能影响限界上下文的边界,却不能成其为划分微服务的依据。例如,根据复用要求单独划分出来的限界上下文也可以以组件而非服务的形式部署,这也充分说明了限界上下文不一定等同于就是微服务。
回到技术部落这个案例。
上一篇文章《识别限界上下文的工作坊演练》提到不能将动词作为业务相关性的判断依据,例如不能将业务服务列表中与“搜索”有关的服务放在一起,也不能将“推荐”有关的服务放在一起。然而,如果考虑到与推荐有关的业务服务需要用到专门的推荐算法,为推荐算法提供支持的数据也不再来自各个由业务划分的限界上下文,而是以OLAP角度,通过ETL等方式将各个业务数据库的数据抽取到数据仓库中,同时还需要利用类似ELK这样的日志分析工具挖掘日志数据,则意味着推荐功能需要专有的技术实现,单独划分出一个推荐上下文就有了充分的理由。
一言以蔽之:如果说业务纬度是划分限界上下文的主要依据,则团队纬度和技术纬度则是校正限界上下文边界的考量因素,进一步,还可作为划分微服务的依据。