最近在看配置中心的一些设计,好像基本都是五花八门,主要看的是还是携程的 Apollo 这个开源的配置中心项目。一直以来都觉得配置中心很重要,因为这对于灰度发布,线上实施干预都有非常重大的作用。但是嘛,你们都知道我有多懒,所以又一直没去好好了解一下,今天趁这个时间跟大家聊聊配置一个合格的配置中心应有的素养。
- 首先什么是配置?
- 配置有什么获取方式?
- 为什么需要实时变更配置?
- 为什么需要配置中心
- 配置中心的分层有必要吗?
- 实时变更配置的方式有几种?
- 配置中心还有什么其他基本的素养?
- 一个实时推送的配置中心架构是怎样的?
01、首先什么是配置?
我的理解是,配置是同一个程序在不同场景不同环境下做出不同表现的一个可变动频繁的点。配置在启动的时候通过各种形式进行获取,在整个生命流程中配置一般来说,是只读的,程序是不会主动去变更的,只有其他地方变更了之后才会触发程序的变更。
最经典的配置有两类,一类是数值型,比如客户的授信额度比例。一类是 Bool 型,用来对某些功能做禁用或启用。
- public class configuration {
- private int NUMBER_CONFIG = 5;
- private boolean SWITCH_CONFIG = true;
- public void config(){
- if(SWITCH_CONFIG){
- System.out.println("YES");
- }
- System.out.println("print YES" + NUMBER_CONFIG);
- }
- }
02、配置有什么获取方式?
配置的获取方式不外乎5种。Hard Code、配置文件、环境变量、数据库获取、启动参数,外部 server 获取。
喇喇喇。上面我写的那堆玩意就是 Hard Code 的。什么叫 Hard Code,就是代码写得跟铁似的硬邦邦的你敲一下还会叮的一生那种。
配置文件,呐,平时用的比较多还是配置文件,比如 Spring 的 application.xml 啊,someFool.properties。
环境变量,嗯,比如 JAVA_HOME 之类的在操作系统上的环境变量。
数据库获取,就是启动的时候或者定时去数据库捞一下。
启动参数,就是作为启动的时候带的参数。比如 java -jar start.jar big。最后的 big 就是启动参数,也是配置项的一种。
外部 server 获取,意思就是这个配置项呢,是其他系统维护的,比如说存款准备金,就是一个央妈这个超级中心维护的配置项,所有的中小企业都要去央妈获取。
03、为什么需要实时变更配置?
人都是善变的,别问我为什么。。。老板昨天说咱有钱,就给客户爸爸们发钱吧,一单 15% 。今天发现银包撑不住了,跟我说大蕉同学我不管你怎么搞你赶紧把这个功能下了,我又不想发版本,所以就需要实时变更配置了。就这么简单,人都是善变的。
04、为什么需要配置中心?
一个应用两个应用还行,要是有100个应用,还真不知道怎么管理,实时推送配置项也成了一大难题。现在传统的比较主流的配置项管理做法有这么几种。
改代码重新打包(真特么傻逼)
改配置项重启。(说实话蛮那啥的)
改数据库重启。(一样)
改数据库定时获取。(浪费资源,一直在轮询,还需要一定时间才生效)
只能说,时间太长了,太浪费了,少则30秒多则60分钟(不要问我为什么是60分钟,因为有一些傻逼应用启动起来就特么要这么久)。
所以有个配置中心来帮你管理这些东西,不亦说乎?
05、配置中心的分层有必要吗?
现在主流的配置中心都会进行分层,五花八门,有的恨不得一台机器一台机器管理,有的又特么的一个集群只能统一配置。其实只需要下面几个维度就够了,应用维度,集群维度,机器维度。有了这三个维度基本可以满足99.9999%的需求,如果发现还不能满足,那么你所说的不在我这个范围。(偷笑ing)
06、实时变更配置的方式有几种?
从广义来说,就两种,一是定时拉取,而是实时推送。
定时拉取的有:定时从数据库拉取,定时从外部 server 拉取,定时从共享配置文件读取。
实时推送的有:用 kafka 等消息队列作为消费端消费,用 webSocket、 http 或者 rpc 接口 作为服务端接收推送。
07、配置中心还有什么其他基本的素养?
- 可分区推送
可以作为 A/B Test 的一种手段,也可以用来预防配置出错。
- 审批
一般来说配置变更是一件不小的事情,还是要有审批链的。
- 环境识别
对于 DEV 开发环境,STG 测试环境,PRD 生产环境要能做到针对环境不同读取不同的配置项。
- 持久化
有时候配置中心会挂了,而这时候是不应该影响应用的,所以应该要有持久化的机制来保证服务恢复后的数据问题。
- 监控
用户能实时知道发布到什么哪了,哪些机器是新配置哪些机器是旧配置,以及基于版本的实实时回滚功能。
- 操作审计
对配置的一切操作都会有操作记录,以便后期监控和审计用。
08、一个实时推送的配置中心架构是怎样的?
一个配置中心最朴素的架构就是上面这样。用户发布配置修改,配置中心通知应用进行更新,应用获取最新配置。
再细一点呢,分为客户端和配置中心两路来讲。
- 客户端
客户端在应用启动的同事,要启动一个服务专门用来接收来自配置中心的通知,这个服务可以是 kafka 、RocketMQ、WebSocket、RPC、DUBBO 等能作为服务提供给外部的接口,并主动向配置中心注册自己。
服务提供完之后,开始扫描自己所需要的配置项,并根据配置主动从本地读取(本地开发模式)或从配置中心获取相应环境的配置项。
读取完成后放在内存中,所有对于配置的读取都从内存中读取,对于JAVA来说可能就是一个 static 变量或者一个 HashMap 。
如果配置中心通知变更了,那么直接读取新的值,然后替换内存中的配置项,就 ok 了。
- 配置中心
配置中心要做的事情,就是根据用户的操作,对配置项进行发布,通过调用客户端提供的接口或者发送消息,通知客户端来更新消息,或者直接把更新的配置项推过去。非常朴素但是非常好用。