“极客时间”《DDD 实战》课程笔记 (七)微服务向DDD转型

发表于2020-03-08,长度2357, 108个单词, 6分钟读完
Flag Counter

这是一系列学习笔记,对象是 极客时间 上面的收费课程 《 DDD实战 》。这一篇记录一下如何将现有非DDD的项目改造成DDD项目。

演进策略

绞杀者策略

绞杀者策略是一种逐步剥离原系统业务能力、用新服务逐步替代原有系统的策略。随着时间的推移,大部分原有系统的功能将被独立为新服务,这样就慢慢绞杀掉了原来的系统。绞杀者策略类似建筑拆迁,完成部分新建筑物后,然后拆除部分旧建筑物。

修缮者策略

修缮者策略是一种维持原有系统整体能力不变,逐步优化系统整体能力的策略。它是在现有系统的基础上,剥离影响整体业务的部分功能,加入新服务,比如高性能要求的功能,代码质量不高或者版本发布频率不一致的功能等。 修缮者策略类似古建筑修复,将存在问题的部分功能重建或者修复后,重新加入到原有的建筑中,保持建筑原貌和功能不变。一般人从外表感觉不到这个变化,但是建筑物质量却得到了很大的提升。

*另起炉灶

这是这种比较暴力的做法,将原有系统推倒重做。建设期间,原有单体系统照常运行,一般会停止开发新需求。而新系统则会组织新的项目团队,按照原有系统的功能域,重新做领域建模,开发新的微服务。在完成数据迁移后,进行新旧系统切换。

一般不建议采用这种策略,因为系统重构后的不稳定性、大量未知的潜在技术风险和新的开发模式下项目团队磨合等不确定性因素,会导致项目实施难度大大增加。

领域策略选择

新建系统

新建系统分为简单和复杂领域建模两种场景。

简单领域

简单的业务领域,一个领域就是一个小子域。在这个小域内,领域建模过程相对简单,直接采用事件风暴构建领域模型就可以了。

复杂领域建模

复杂的业务领域可能需要多级拆分后才能开始领域建模。领域拆分为子域,子域可能还需要进一步拆分。如果不做细分,由于问题域太大,领域建模的工程量会非常浩大。不太可能通过事件风暴就轻松完成一个很大的领域建模;即使勉强完成,效果也不一定好。

  • 第一步,拆分子域建立领域模型。根据业务领域的特点,结合领域专家和项目团队的讨论,将领域逐级分解为大小合适的子域,针对子域采用事件风暴,划分聚合和限界上下文,初步确定子域内的领域模型。
  • 第二步,领域模型微调。微调的过程重点考虑不同领域模型中聚合的重组。同时考虑领域模型和聚合的边界,服务以及事件之间的依赖关系,确定最终的领域模型。
  • 第三步,微服务的设计和拆分。根据领域模型和微服务拆分原则,完成微服务的拆分和设计。

遗留系统

将部分功能独立为微服务,整体保持不变。比如将面临性能瓶颈的模块拆分为微服务,只需要将这一特定功能,理解为一个简单子领域,参考简单领域建模的方式就可以了。在微服务设计中,还要考虑新老系统之间服务和业务的兼容,必要时可引入防腐层。

这样的说法有点水啊

误区

  • 所有领域都用DDD

DDD 从战略设计到战术设计,是一个相对复杂的过程,首先企业内要培养 DDD 的文化,其次对团队成员的设计和技术能力要求相对比较高。在资源有限的情况下,应聚焦核心域,建议先从富领域模型的核心域开始,而不必一下就在全业务域推开。

  • 全部采用 DDD 战术设计方法

DDD 有很多的概念和战术设计方法,比如聚合根和值对象等。聚合根利用仓储管理聚合内实体数据之间的一致性,这种方法对于管理新建和修改数据非常有效,比如在修改订单数据时,它可以保证订单总金额与所有商品明细金额的一致,但它并不擅长较大数据量的查询处理,甚至有延迟加载进而影响效率的问题。而传统的设计方法,可能一条简单的 SQL 语句就可以很快地解决问题。

在很多贫领域模型的业务,比如数据统计和分析,DDD 很多方法可能都用不上,或用得并不顺手,而传统的方法很容易就解决了。因此,在遵守领域边界和微服务分层等大原则下,进行战术设计时,应该选择最适合的方法。这里要以快速、高效解决实际问题为最佳,不要为做 DDD 而做 DDD。

  • 重战术设计而轻战略设计

很多学习 DDD同学的目的可能是为了开发微服务,因此更看重 DDD 的战术设计实现。殊不知 DDD 是一种从领域建模到微服务落地的全方位的解决方案。战略设计时构建的领域模型,是微服务设计和开发的输入,它确定了微服务的边界、聚合、代码对象以及服务等关键领域对象。领域模型边界划分得清不清晰,领域对象定义得明不明确,会决定微服务的设计和开发质量。没有领域模型的输入,基于 DDD 的微服务的设计和开发将无从谈起。

微服务拆分考虑因素

  • 基于领域模型

基于领域模型进行拆分,围绕业务领域按职责单一性、功能完整性拆分。

  • 基于业务需求变化频率

识别领域模型中的业务需求变动频繁的功能,考虑业务变更频率与相关度,将业务需求变动较高和功能相对稳定的业务进行分离。这是因为需求的经常性变动必然会导致代码的频繁修改和版本发布,这种分离可以有效降低频繁变动的敏态业务对稳态业务的影响。

  • 基于应用性能

识别领域模型中性能压力较大的功能。因为性能要求高的功能可能会拖累其它功能,在资源要求上也会有区别,为了避免对整体性能和资源的影响,我们可以把在性能方面有较高要求的功能拆分出去。

  • 基于组织架构和团队规模

除非有意识地优化组织架构,否则微服务的拆分应尽量避免带来团队和组织架构的调整,避免由于功能的重新划分,而增加大量且不必要的团队之间的沟通成本。拆分后的微服务项目团队规模保持在 10~12 人左右为宜。

  • 基于安全边界

有特殊安全要求的功能,应从领域模型中拆分独立,避免相互影响。

  • 基于技术异构等因素

领域模型中有些功能虽然在同一个业务域内,但在技术实现时可能会存在较大的差异,也就是说领域模型内部不同的功能存在技术异构的问题。由于业务场景或者技术条件的限制,有的可能用.NET,有的则是 Java,有的甚至大数据架构。对于这些存在技术异构的功能,可以考虑按照技术边界进行拆分。

Written on March 8, 2020
分类: dev, 标签: ddd
如果你喜欢,请赞赏! davelet