合格的配置中心應(yīng)有的素養(yǎng)
最近在看配置中心的一些設(shè)計(jì),好像基本都是五花八門,主要看的是還是攜程的 Apollo 這個(gè)開(kāi)源的配置中心項(xiàng)目。一直以來(lái)都覺(jué)得配置中心很重要,因?yàn)檫@對(duì)于灰度發(fā)布,線上實(shí)施干預(yù)都有非常重大的作用。但是嘛,你們都知道我有多懶,所以又一直沒(méi)去好好了解一下,今天趁這個(gè)時(shí)間跟大家聊聊配置一個(gè)合格的配置中心應(yīng)有的素養(yǎng)。
- 首先什么是配置?
- 配置有什么獲取方式?
- 為什么需要實(shí)時(shí)變更配置?
- 為什么需要配置中心
- 配置中心的分層有必要嗎?
- 實(shí)時(shí)變更配置的方式有幾種?
- 配置中心還有什么其他基本的素養(yǎng)?
- 一個(gè)實(shí)時(shí)推送的配置中心架構(gòu)是怎樣的?
01、首先什么是配置?
我的理解是,配置是同一個(gè)程序在不同場(chǎng)景不同環(huán)境下做出不同表現(xiàn)的一個(gè)可變動(dòng)頻繁的點(diǎn)。配置在啟動(dòng)的時(shí)候通過(guò)各種形式進(jìn)行獲取,在整個(gè)生命流程中配置一般來(lái)說(shuō),是只讀的,程序是不會(huì)主動(dòng)去變更的,只有其他地方變更了之后才會(huì)觸發(fā)程序的變更。
最經(jīng)典的配置有兩類,一類是數(shù)值型,比如客戶的授信額度比例。一類是 Bool 型,用來(lái)對(duì)某些功能做禁用或啟用。
- 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、配置文件、環(huán)境變量、數(shù)據(jù)庫(kù)獲取、啟動(dòng)參數(shù),外部 server 獲取。
喇喇喇。上面我寫(xiě)的那堆玩意就是 Hard Code 的。什么叫 Hard Code,就是代碼寫(xiě)得跟鐵似的硬邦邦的你敲一下還會(huì)叮的一生那種。
配置文件,吶,平時(shí)用的比較多還是配置文件,比如 Spring 的 application.xml 啊,someFool.properties。
環(huán)境變量,嗯,比如 JAVA_HOME 之類的在操作系統(tǒng)上的環(huán)境變量。
數(shù)據(jù)庫(kù)獲取,就是啟動(dòng)的時(shí)候或者定時(shí)去數(shù)據(jù)庫(kù)撈一下。
啟動(dòng)參數(shù),就是作為啟動(dòng)的時(shí)候帶的參數(shù)。比如 java -jar start.jar big。最后的 big 就是啟動(dòng)參數(shù),也是配置項(xiàng)的一種。
外部 server 獲取,意思就是這個(gè)配置項(xiàng)呢,是其他系統(tǒng)維護(hù)的,比如說(shuō)存款準(zhǔn)備金,就是一個(gè)央媽這個(gè)超級(jí)中心維護(hù)的配置項(xiàng),所有的中小企業(yè)都要去央媽獲取。
03、為什么需要實(shí)時(shí)變更配置?
人都是善變的,別問(wèn)我為什么。。。老板昨天說(shuō)咱有錢,就給客戶爸爸們發(fā)錢吧,一單 15% 。今天發(fā)現(xiàn)銀包撐不住了,跟我說(shuō)大蕉同學(xué)我不管你怎么搞你趕緊把這個(gè)功能下了,我又不想發(fā)版本,所以就需要實(shí)時(shí)變更配置了。就這么簡(jiǎn)單,人都是善變的。
04、為什么需要配置中心?
一個(gè)應(yīng)用兩個(gè)應(yīng)用還行,要是有100個(gè)應(yīng)用,還真不知道怎么管理,實(shí)時(shí)推送配置項(xiàng)也成了一大難題?,F(xiàn)在傳統(tǒng)的比較主流的配置項(xiàng)管理做法有這么幾種。
改代碼重新打包(真特么傻逼)
改配置項(xiàng)重啟。(說(shuō)實(shí)話蠻那啥的)
改數(shù)據(jù)庫(kù)重啟。(一樣)
改數(shù)據(jù)庫(kù)定時(shí)獲取。(浪費(fèi)資源,一直在輪詢,還需要一定時(shí)間才生效)
只能說(shuō),時(shí)間太長(zhǎng)了,太浪費(fèi)了,少則30秒多則60分鐘(不要問(wèn)我為什么是60分鐘,因?yàn)橛幸恍┥当茟?yīng)用啟動(dòng)起來(lái)就特么要這么久)。
所以有個(gè)配置中心來(lái)幫你管理這些東西,不亦說(shuō)乎?
05、配置中心的分層有必要嗎?
現(xiàn)在主流的配置中心都會(huì)進(jìn)行分層,五花八門,有的恨不得一臺(tái)機(jī)器一臺(tái)機(jī)器管理,有的又特么的一個(gè)集群只能統(tǒng)一配置。其實(shí)只需要下面幾個(gè)維度就夠了,應(yīng)用維度,集群維度,機(jī)器維度。有了這三個(gè)維度基本可以滿足99.9999%的需求,如果發(fā)現(xiàn)還不能滿足,那么你所說(shuō)的不在我這個(gè)范圍。(偷笑ing)
06、實(shí)時(shí)變更配置的方式有幾種?
從廣義來(lái)說(shuō),就兩種,一是定時(shí)拉取,而是實(shí)時(shí)推送。
定時(shí)拉取的有:定時(shí)從數(shù)據(jù)庫(kù)拉取,定時(shí)從外部 server 拉取,定時(shí)從共享配置文件讀取。
實(shí)時(shí)推送的有:用 kafka 等消息隊(duì)列作為消費(fèi)端消費(fèi),用 webSocket、 http 或者 rpc 接口 作為服務(wù)端接收推送。
07、配置中心還有什么其他基本的素養(yǎng)?
- 可分區(qū)推送
可以作為 A/B Test 的一種手段,也可以用來(lái)預(yù)防配置出錯(cuò)。
- 審批
一般來(lái)說(shuō)配置變更是一件不小的事情,還是要有審批鏈的。
- 環(huán)境識(shí)別
對(duì)于 DEV 開(kāi)發(fā)環(huán)境,STG 測(cè)試環(huán)境,PRD 生產(chǎn)環(huán)境要能做到針對(duì)環(huán)境不同讀取不同的配置項(xiàng)。
- 持久化
有時(shí)候配置中心會(huì)掛了,而這時(shí)候是不應(yīng)該影響應(yīng)用的,所以應(yīng)該要有持久化的機(jī)制來(lái)保證服務(wù)恢復(fù)后的數(shù)據(jù)問(wèn)題。
- 監(jiān)控
用戶能實(shí)時(shí)知道發(fā)布到什么哪了,哪些機(jī)器是新配置哪些機(jī)器是舊配置,以及基于版本的實(shí)實(shí)時(shí)回滾功能。
- 操作審計(jì)
對(duì)配置的一切操作都會(huì)有操作記錄,以便后期監(jiān)控和審計(jì)用。
08、一個(gè)實(shí)時(shí)推送的配置中心架構(gòu)是怎樣的?
一個(gè)配置中心最樸素的架構(gòu)就是上面這樣。用戶發(fā)布配置修改,配置中心通知應(yīng)用進(jìn)行更新,應(yīng)用獲取最新配置。
再細(xì)一點(diǎn)呢,分為客戶端和配置中心兩路來(lái)講。
- 客戶端
客戶端在應(yīng)用啟動(dòng)的同事,要啟動(dòng)一個(gè)服務(wù)專門用來(lái)接收來(lái)自配置中心的通知,這個(gè)服務(wù)可以是 kafka 、RocketMQ、WebSocket、RPC、DUBBO 等能作為服務(wù)提供給外部的接口,并主動(dòng)向配置中心注冊(cè)自己。
服務(wù)提供完之后,開(kāi)始掃描自己所需要的配置項(xiàng),并根據(jù)配置主動(dòng)從本地讀?。ū镜亻_(kāi)發(fā)模式)或從配置中心獲取相應(yīng)環(huán)境的配置項(xiàng)。
讀取完成后放在內(nèi)存中,所有對(duì)于配置的讀取都從內(nèi)存中讀取,對(duì)于JAVA來(lái)說(shuō)可能就是一個(gè) static 變量或者一個(gè) HashMap 。
如果配置中心通知變更了,那么直接讀取新的值,然后替換內(nèi)存中的配置項(xiàng),就 ok 了。
- 配置中心
配置中心要做的事情,就是根據(jù)用戶的操作,對(duì)配置項(xiàng)進(jìn)行發(fā)布,通過(guò)調(diào)用客戶端提供的接口或者發(fā)送消息,通知客戶端來(lái)更新消息,或者直接把更新的配置項(xiàng)推過(guò)去。非常樸素但是非常好用。