<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Infra on 翟志军 Jack Zhai</title>
    <link>https://showme.codes/tags/infra/</link>
    <description>Recent content in Infra on 翟志军 Jack Zhai</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <copyright>showme.codes</copyright>
    <lastBuildDate>Sat, 27 Jan 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://showme.codes/tags/infra/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>如何将DDD应用到基础设施设计？</title>
      <link>https://showme.codes/zh-cn/2024-01-27-ddd-infra-integrated/</link>
      <pubDate>Sat, 27 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://showme.codes/zh-cn/2024-01-27-ddd-infra-integrated/</guid>
      <description>&lt;p&gt;前段时间在面试的时候，面试官问到：你是如何将DDD（领域驱动设计）应用到基础设施的？&lt;/p&gt;
&lt;p&gt;我很惊讶，终于有人问我这个问题了。&lt;/p&gt;
&lt;p&gt;在过去从事基础设施（DevOps、SRE、运维）的这5年里，我经常说起DDD是一种思维模式，可以应用到任何的领域，包括基础设施的设计。&lt;/p&gt;
&lt;p&gt;但是，从来没有人像这位面试官问起我具体的做法。&lt;/p&gt;
&lt;p&gt;为什么没有人问？原因大概是这两个概念通常是不会放在一起的。大多数开发不会深入理解基础设施的设计，而大多数从事基础设施设计的人是不会接触到DDD。而且，开发人员对于DDD的理解，也仅局限于用它开发业务系统。&lt;/p&gt;
&lt;p&gt;我就是那少部分人，即做基础设施的设计，又觉得自己懂DDD的人。&lt;/p&gt;
&lt;p&gt;说回问题本身。&lt;/p&gt;
&lt;h2 id=&#34;我所理解的ddd&#34;&gt;我所理解的DDD&lt;/h2&gt;
&lt;p&gt;我首先会向提问的人澄清我所理解的DDD。&lt;/p&gt;
&lt;p&gt;为什么要这样呢？很久以前有一次面试，因为我说我擅长DevOps，面试官就认为我不懂GitOps。然后在这个点上他就认为我不适合，不再问我DevOps方面的问题。我只能说没有缘份。&lt;/p&gt;
&lt;p&gt;我是这样解释DDD的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;就像开发一个象棋游戏，不论你要开发手机端，还是web端，象棋规则本身都是不变的。这个规则本身就可以理解为“领域”。
其它所有的技术（包括架构）都是具体实现，它们应该由“领域”来驱动设计。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当时的解释与以上的解释大差不差。&lt;/p&gt;
&lt;h2 id=&#34;将ddd应用到基础设施设计的具体做法&#34;&gt;将DDD应用到基础设施设计的具体做法&lt;/h2&gt;
&lt;p&gt;那么该如何将DDD应用到基础设施的设计呢？&lt;/p&gt;
&lt;p&gt;DDD的思维方式要求我们首先问：我们要设计的软件的领域（核心）问题是什么？&lt;/p&gt;
&lt;p&gt;基础设施的领域问题是什么？我的回答是&lt;strong&gt;配置&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我认为基础设施的搭建、维护，本质就是配置的设计、部署、维护。&lt;/p&gt;
&lt;p&gt;寻找领域（本质）问题的能力是DDD的核心能力。&lt;/p&gt;
&lt;p&gt;为了让读者更好理解，我们以一个一个基于云上的虚拟机的分布式系统为例。它的基础设施就包括：vpc、LB、MQ、DB等。&lt;/p&gt;
&lt;p&gt;要搭建、维护这一套基础设施。&lt;/p&gt;
&lt;p&gt;根据“配置管理是基础设施设计的核心问题”，我首先将基础设施的所有的配置放在清单代码（并不一定是一个文件）中，如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;vpc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# ....&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;LB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# ...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;DB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# ...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;MQ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# ...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;APP1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mq_addr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{{ MQ.addr }}&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;db_host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{{ DB.addr }}&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;APP2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mq_addr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{{ MQ.addr }}&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;db_host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{{ DB.addr }}&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app1_addr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{{ APP1.addr }}&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;从清单中，你看不出它使用何种部署方式、部署顺序。你只知道APP1引用了MQ和DB，APP2会调用APP2这样纯粹的领域知识。&lt;/p&gt;
&lt;p&gt;现实通常是多个环境，所以，我一开始就会将不同环境的值从清单上抽离到独立的文件夹中。&lt;/p&gt;
&lt;p&gt;第二步，我才会考虑如何部署它们。这时，我通过两个工具实现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Terraform负责云基础设施；&lt;/li&gt;
&lt;li&gt;Ansible负责业务基础设施。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ansible是可以直接读取我们的YAML格式配置文件。而Terraform代码引用YAML代码，就没有那么方便了。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
