如何将DDD应用到基础设施设计?

前段时间在面试的时候,面试官问到:你是如何将DDD(领域驱动设计)应用到基础设施的? 我很惊讶,终于有人问我这个问题了。 在过去从事基础设施(DevOps、SRE、运维)的这5年里,我经常说起DDD是一种思维模式,可以应用到任何的领域,包括基础设施的设计。 但是,从来没有人像这位面试官问起我具体的做法。 为什么没有人问?原因大概是这两个概念通常是不会放在一起的。大多数开发不会深入理解基础设施的设计,而大多数从事基础设施设计的人是不会接触到DDD。而且,开发人员对于DDD的理解,也仅局限于用它开发业务系统。 我就是那少部分人,即做基础设施的设计,又觉得自己懂DDD的人。 说回问题本身。 我所理解的DDD 我首先会向提问的人澄清我所理解的DDD。 为什么要这样呢?很久以前有一次面试,因为我说我擅长DevOps,面试官就认为我不懂GitOps。然后在这个点上他就认为我不适合,不再问我DevOps方面的问题。我只能说没有缘份。 我是这样解释DDD的: 就像开发一个象棋游戏,不论你要开发手机端,还是web端,象棋规则本身都是不变的。这个规则本身就可以理解为“领域”。 其它所有的技术(包括架构)都是具体实现,它们应该由“领域”来驱动设计。 当时的解释与以上的解释大差不差。 将DDD应用到基础设施设计的具体做法 那么该如何将DDD应用到基础设施的设计呢? DDD的思维方式要求我们首先问:我们要设计的软件的领域(核心)问题是什么? 基础设施的领域问题是什么?我的回答是配置。 我认为基础设施的搭建、维护,本质就是配置的设计、部署、维护。 寻找领域(本质)问题的能力是DDD的核心能力。 为了让读者更好理解,我们以一个一个基于云上的虚拟机的分布式系统为例。它的基础设施就包括:vpc、LB、MQ、DB等。 要搭建、维护这一套基础设施。 根据“配置管理是基础设施设计的核心问题”,我首先将基础设施的所有的配置放在清单代码(并不一定是一个文件)中,如下: vpc: # .... LB: # ... DB: # ... MQ: # ... APP1: mq_addr: "{{ MQ.addr }}" db_host: "{{ DB.addr }}" APP2: mq_addr: "{{ MQ.addr }}" db_host: "{{ DB.addr }}" app1_addr: "{{ APP1.addr }}" 从清单中,你看不出它使用何种部署方式、部署顺序。你只知道APP1引用了MQ和DB,APP2会调用APP2这样纯粹的领域知识。 现实通常是多个环境,所以,我一开始就会将不同环境的值从清单上抽离到独立的文件夹中。 第二步,我才会考虑如何部署它们。这时,我通过两个工具实现: Terraform负责云基础设施; Ansible负责业务基础设施。 Ansible是可以直接读取我们的YAML格式配置文件。而Terraform代码引用YAML代码,就没有那么方便了。 ...

2024-01-27 · 1 min · 78 words · 翟志军 Jack Zhai