我们前面已经讲了很多 DDD 的设计方法和实践案例。虽然 DDD 的设计思想和方法很好,但由于企业发展历程以及企业技术和文化的不同,DDD 和微服务的实施策略也会有差异。那么面对这种差异,我们应该如何落地 DDD 和微服务呢?今天我们就来聊聊微服务的设计原则和演进策略。
在从单体向微服务演进时,演进策略大体分为两种:绞杀者策略和修缮者策略。
绞杀者策略是一种逐步剥离业务能力,用微服务逐步替代原有单体系统的策略。它对单体系统进行领域建模,根据领域边界,在单体系统之外,将新功能和部分业务能力独立出来,建设独立的微服务。新微服务与单体系统保持松耦合关系。
随着时间的推移,大部分单体系统的功能将被独立为微服务,这样就慢慢绞杀掉了原来的单体系统。绞杀者策略类似建筑拆迁,完成部分新建筑物后,然后拆除部分旧建筑物。
修缮者策略是一种维持原有系统整体能力不变,逐步优化系统整体能力的策略。它是在现有系统的基础上,剥离影响整体业务的部分功能,独立为微服务,比如高性能要求的功能,代码质量不高或者版本发布频率不一致的功能等。
通过这些功能的剥离,我们就可以兼顾整体和局部,解决系统整体不协调的问题。修缮者策略类似古建筑修复,将存在问题的部分功能重建或者修复后,重新加入到原有的建筑中,保持建筑原貌和功能不变。一般人从外表感觉不到这个变化,但是建筑物质量却得到了很大的提升。
其实还有第三种策略,就是另起炉灶,顾名思义就是将原有的系统推倒重做。建设期间,原有单体系统照常运行,一般会停止开发新需求。而新系统则会组织新的项目团队,按照原有系统的功能域,重新做领域建模,开发新的微服务。在完成数据迁移后,进行新旧系统切换。
对于大型核心系统我一般不建议采用这种策略,这是因为系统重构后的不稳定性、大量未知的潜在技术风险和新的开发模式下项目团队磨合等不确定性因素,会导致项目实施难度大大增加。
由于企业内情况千差万别,发展历程也不一样,有遗留单体系统的微服务改造,也有全新未知领域的业务建模和系统设计,还有遗留系统局部优化的情况。不同场景下,领域建模的策略也会有差异。下面我们就分几类场景来看看如何进行领域建模。
新建系统又分为简单和复杂领域建模两种场景。
简单领域建模
简单的业务领域,一个领域就是一个小的子域。在这个小的问题域内,领域建模过程相对简单,直接采用事件风暴的方法构建领域模型就可以了。
复杂领域建模
对于复杂的业务领域,领域可能需要多级拆分后才能开始领域建模。领域拆分为子域,甚至子域还需要进一步拆分。比如:保险它需要拆分为承保、理赔、收付费和再保等子域,承保子域再拆分为投保、保单管理等子子域。复杂领域如果不做进一步细分,由于问题域太大,领域建模的工程量会非常浩大。你不太容易通过事件风暴,完成一个很大的领域建模,即使勉强完成,效果也不一定好。
对于复杂领域,我们可以分三步来完成领域建模和微服务设计。
第一步,拆分子域建立领域模型
根据业务领域的特点,参考流程节点边界或功能聚合模块等边界因素。结合领域专家和项目团队的讨论,将领域逐级分解为大小合适的子域,针对子域采用事件风暴,划分聚合和限界上下文,初步确定子域内的领域模型。
第二步,领域模型微调
梳理领域内所有子域的领域模型,对各子域领域模型进行微调。微调的过程重点考虑不同领域模型中聚合的重组。同步考虑领域模型和聚合的边界,服务以及事件之间的依赖关系,确定最终的领域模型。
第三步,微服务的设计和拆分
根据领域模型和微服务拆分原则,完成微服务的拆分和设计。