<?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>Configuration on 翟志军 Jack Zhai</title>
    <link>https://showme.codes/tags/configuration/</link>
    <description>Recent content in Configuration on 翟志军 Jack Zhai</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <copyright>showme.codes</copyright>
    <lastBuildDate>Mon, 12 Jun 2023 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://showme.codes/tags/configuration/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>微服务架构下的配置治理模式</title>
      <link>https://showme.codes/zh-cn/2023-06-12-patterns-of-configuration-under-microservice/</link>
      <pubDate>Mon, 12 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://showme.codes/zh-cn/2023-06-12-patterns-of-configuration-under-microservice/</guid>
      <description>&lt;p&gt;微服务被滥用是不争的事实。被滥用的同时，很少人留意到它所带来的配置治理的问题。本文我们介绍两种常见的治理模式。&lt;/p&gt;
&lt;h2 id=&#34;基于common的配置治理模式&#34;&gt;基于common的配置治理模式&lt;/h2&gt;
&lt;p&gt;当微服务数量多时，开发人员倾向于创建这样的配置文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;common-redis.json&lt;/li&gt;
&lt;li&gt;common-mysql.json&lt;/li&gt;
&lt;li&gt;common-mq.json&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;甚至还有会有common.json这种从名字上就不知道它的作用的配置。但是，几乎所有的微服务都会引用common.json这个配置。原因如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在common.json可以无脑增加配置项，不需要改业务代码；&lt;/li&gt;
&lt;li&gt;配置项可能是被n个微服务引用，为了这一个配置项，又新增一个配置文件，不值得。common.json看起来是最合适的。反正每个微服务都已经引用了common.json。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;![](/assets/images/Pasted image 20221220161521.png)&lt;/p&gt;
&lt;p&gt;基于common的配置，在写入配置项的时候是爽了，但是，也带来了问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;改了common.json文件中的配置后，很难确认这个变更会影响到哪里，因为每个微服务都引用了common.json；&lt;/li&gt;
&lt;li&gt;common.json会变得越来越大；&lt;/li&gt;
&lt;li&gt;并不是每次发布，都发布所有的微服务。所以，微服务A可能采用的是common.json的v1版本，而微服务B可能采用的是common.json的v2版本。&lt;/li&gt;
&lt;li&gt;随着时间迁移，谁也不敢动common.json中的配置，即使有些配置项已经很久没有被使用了。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;基于服务级别粒度的配置治理模式&#34;&gt;基于服务级别粒度的配置治理模式&lt;/h2&gt;
&lt;p&gt;基于服务级别粒度的配置方式，很容易理解，如下图：
![](/assets/images/Pasted image 20221220161557.png)
每个服务只引用一个配置文件。此模式完全避免了基于common的治理模式所带来的问题。但是，又带来了新的问题，即不同的微服务配置之间出现大量的重复配置。修改大量重复配置容易出错，且痛苦。&lt;/p&gt;
&lt;p&gt;大量配置重复的问题，可以通过类似Jsonnet或者CUE这样的配置编程语言解决。如下所示：&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://showme.codes/assets/images/microservice-common-config.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;当修改metrics.libsonnet时，我们很容易就知道这个变更将直接影响：microservice-c.jsonnet和microservice-a.jsonnet。进而，我们也就可以知道了它将间接影响microservice-c和microservice-b两个服务。&lt;/p&gt;
&lt;p&gt;不存在没有缺点的解决方案。使用Jsonnet和CUE这样的语言，意味着一定的学习成本和现在有的工程的改造成本（引入新的构建工具和对现在有的配置的转换）。&lt;/p&gt;
&lt;h2 id=&#34;不论哪种模式你都必须要做到&#34;&gt;不论哪种模式，你都必须要做到&lt;/h2&gt;
&lt;p&gt;不论哪种配置治理模式，都必须要做到：配置应该尽量小。&lt;/p&gt;
&lt;p&gt;至于小到什么程度？这个问题回答了，作用也不大。就像菜谱上写的是10克的香精，也没有几个人在放香精时进行称重，而是凭感觉。&lt;/p&gt;
&lt;p&gt;如果真要我回答，我的回答是：作为一个逻辑单元，多一行代码是多余，少一行代码则不行。&lt;/p&gt;
&lt;h2 id=&#34;成本&#34;&gt;成本&lt;/h2&gt;
&lt;p&gt;当我提出采用一种新的配置编程语言来统一所有的配置时，团队里的人都反对。行业里其他的人，也啧啧着这样做所带来的成本。&lt;/p&gt;
&lt;p&gt;所以，以下是我们团队经验，供大家参考：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Jsonnet的学习成本：像Jsonnet这样专为配置而生的配置编程语言，语法也只有一张A4纸，非常值得投入。我们团队里两个不懂编程的刚毕业没有多久的运维小年轻，很快就上手了。多快？半天左右吧。&lt;/li&gt;
&lt;li&gt;构建工具Bazel的学习成本：Jsonnet本身的构建命令就和Java的javac一样低级，所以，需要借助其它构建工具。我们选择Bazel。它支持Jsonnet的单元测试。我们顺便实现了配置的自动化测试。Bazel的学习只需要团队里的几个人会就可以了。这个工具本身其实不难，但是因为中文学习教程太少了，导致了学习成本高。&lt;/li&gt;
&lt;li&gt;其它配置格式转换成Jsonnet格式的成本：这个应该是我们成本最高的，也是风险最高的。因为一个配置错，可能带来线上事故。这个过程也是一个还债的过程。以前不合理的配置，在这个过程中会被发现。我们转换的过程是
&lt;ol&gt;
&lt;li&gt;通过自动转换工具将旧配置转成json格式，json格式与jsonnet格式是兼容的，所以就相当于自动得到了jsonnet格式的配置；&lt;/li&gt;
&lt;li&gt;将公共配置抽离出来，比如redis的配置。并对敏感配置进行加密处理。这个过程是重建配置的过程；&lt;/li&gt;
&lt;li&gt;将所有的配置转换完成后，再与原来的配置的json格式进行内容级别的对比。如果没有区别，就代表转换成功。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因为我们很早之前就对配置进行了标准化，所以对我们来说这个转换成本和配置的量对比起来，也不算太高。而这个成本绝大多数都是由基础设施团队完成，而不是业务开发团队。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
