不同的类型的配置最开始可能都可以以配置文件的形式将就一下,但是其对管理和使用的需求却是相差很大的。etcd提供了一个很好的机制做为开头,但是未必适合所有的场景。
在配置文件中的配置可以分为以下几类:
组网配置,也称为服务注册和发现,以ip,端口,用户名,密码四个属性为主要代表
A/B测试,小流量,降级开关等流量控制配置
营销规则,运营规则,计价规则类配置
文案等纯k/v配置
最开始的时候,这些配置都是保存在配置文件中的。但是不同类型的配置其实有不同的需求,妄图用一个etcd来解决所有问题是典型的有锤子去找钉子的行为。
组网配置是非常值得从配置文件中抽取来好好管理的东西。很多软件工程中的困难问题,都来自于大家不能很容易的“搭环境”。各种场合都可以听到抱怨说搭个环境太难了。而其中最困难的就是把一个十多个模块的系统用配置文件给拼装到一起。
组网配置的核心需求是四点:
对“服务”的抽象建模
set(或者region)模型的支持
(可选)上下游依赖管理
生效速度与一致性
组网配置其实是对集群进行建模。把集群一个集群抽象为一个set或者一个region。然后一个set里有多种名称的服务,一个服务会有多个实例。每个实例又有自己的ip端口这些属性。etcd自身是没有规定如何去建立这个抽象的。需要使用etcd的人去建模。
比较挫的实现是一个set里的服务是对所有服务都可见的,而这就隐含了所有人在依赖所有人。比较好的方式是一个服务申明自己所有依赖的服务,配置里只引用自己所依赖的服务。但是依赖管理比较难推广,所以不是必须的。
大部分业务系统里对组网配置没有很强的一致性要求以及生效速度的要求。与数据系统不同,主从切换一致性出了问题,会导致严重的数据丢失。所以etcd的强一致和生效速度在数据库领域有一些应用范围。但是其实深究下去,数据库也更多的是把paxos/raft做在数据库自身的分布式协议内部了,而不是外挂一个etcd来使用。在业务层,etcd的强一致性真没有多大用处。那么剩下的就是一个基于watch的即时生效了。但是业务系统真的需要依赖watch即时生效来获得高可用性吗?显然是否定的。大部分的探活和故障节点摘除都是利用单机的投票机制来实现的(比如nginx的upstream管理)。靠etcd这样上报数据,告警,然后中央节点摘除,必然是要慢一步的。所以对于生效速度和一致性来说,etcd未必有多实用。
流量开关就是第二个上线系统。通过第一个上线系统把代码上线到生产环境,然后再通过第二个上下系统把开关打开,让新代码真正开始被使用起来。流量开关的好处是可以有多个开关同时独立控制,以及精确的流量比例控制,还有快速的的回滚。
流量开关对于配置管理的需求有两点:
规则的下发
非常快的生效速度
流量开关需要下发的配置其实是一堆规则。比如北京,某个产品线,流量打开。但是因为规则数量一般不会特别多,可以全量下发,并对规则进行全量顺序求值。但是假如规则多到了几万条,而使用方是php这样的无状态的系统,每次业务请求对规则匹配的速度又要求很高的话,仍然是很难用全量下发去实现的。
生效速度是流量开关最重要的功能。当我们发现开的流量在线上引起了问题,这个时候是分秒必争的。能不能快速地把流量切回去决定了损失的大小。etcd的watch机制对于流量开关来说非常有用。
营销等业务规则的特点是数量一般会比较多,比如分城市分场景分车型的计价配置。简单的顺序求值不能满足要求。而且这些业务规则一般会有指定的生效时间段,所以没有像流量开关那样突发的要求规则改变的需求。明天的规则,今天能发到线上就可以了。
营销等业务规则对于配置的需求有:
复杂条件的规则检索和匹配(按生效时间,按地理围栏,按人群分类,按产品属性等)
不依赖于快速生效
读取的可靠性
etcd的树状结构可以实现一定程度的索引。但是对于复杂规则的检索和匹配仍然是有很大欠缺的,除非我们愿意在写入的时候建立不同检索维度的树状索引,否则在读取时的匹配成本是无法接受的。
etcd的快速生效机制并没有多大用处。
etcd的http接口依赖于etcd自身服务的可靠性。相对于分发到本地的配置文件,应该是相对来说不可靠一些。与A/B测试这样的流量控制配置不同,业务规则的配置不能是返回true可以,返回false也行的。
这类配置最单纯,依赖最少。但是如果是大量读取的界面上的文案,其实还要考虑一下每次读取的延迟。如果一个页面需要一百多个文案项的读取,把会用到的配置都预读到业务进程内存里是必然的选择
所以对配置读取的需求:
在量大的时候需要低延迟的读取
etcd提供了一个基本的机制,但是对于那些配置会一起使用其实是不清楚的。如果不能全量缓存到本地,预读没有判断好的话,可能会造成读取配置的总耗时过长。
配置其实也有自己的业务逻辑。没有通用的配置系统一说。配置需要理解其对应的管理和使用场景去设计定制的解决方案。