配置中心:將依賴于服務(wù)器環(huán)境的變量進行統(tǒng)一的管理乡数,如:FTP賬號密碼辆布、三方云服務(wù)的服務(wù)地址及相應(yīng)的授權(quán)信息丘侠,以及部分公司內(nèi)部平臺的基本配置危彩。
配置中心解決什么痛點:
1攒磨、將系統(tǒng)的基本配置與應(yīng)用代碼隔離,在一定程度上提高系統(tǒng)安全性汤徽、杜絕基礎(chǔ)配置被誤改的情況娩缰。
2、基礎(chǔ)配置統(tǒng)一管理谒府,便于維護拼坎,需要修改某一配置時不需要登錄到應(yīng)用集群中的每一臺服務(wù)器上進行修改,只需要在配置中心的統(tǒng)一管理平臺進行修改然后作推送操作(這需要看配置中心具體的實現(xiàn))完疫。
3泰鸡、配置中心從某種角度上可以監(jiān)控應(yīng)用的運行狀態(tài)(通過client端和server端的鏈接),雖然沒有提供專業(yè)的監(jiān)控服務(wù)壳鹤。
配置中心的實現(xiàn):
1盛龄、開源實現(xiàn):github上有很多開源的配置中心的實現(xiàn),阿里早期開源的diamond、以及很多興趣愛好者自研的配置中心余舶,下面我給出一個由java實現(xiàn)的也是github上熱度比較高的配置中心:https://github.com/melin/super-diamond啊鸭,之前我們公司內(nèi)部就是用它進行對配置的統(tǒng)一管理。當然github上還有很多其他比較實用熱度也很高的配置中心解決方案匿值、其中也有用python實現(xiàn)的赠制。
下面就我們在使用super-diamond過程中遇到的一些問題進行梳理(抽出相對共性具有代表性的問題),以及我們是如何針對這些問題怎樣對其進行改造挟憔、在改造過程中遇到的問題及應(yīng)對之策钟些,最后介紹我們當前架構(gòu)設(shè)計存在的不足及下一步架構(gòu)發(fā)展的方向。
存在問題:
(1)服務(wù)端的單點問題绊谭,高可用性不強政恍。
(2)前端功能、界面不友好龙誊,對某一工程模塊下某個key配置困難抚垃。
(3)自身協(xié)議喷楣,client與server之間需要雙向通信(client可以pull趟大,server可以push)等。
(4)服務(wù)端的數(shù)據(jù)安全問題铣焊,對client端進行白名單或者簽名驗證逊朽,保證工程配置不被外部環(huán)境竊取。
(5)在統(tǒng)一配置管理界面曲伊,對某一工程配置修改后叽讳,工程需要重啟才能拉取新配置。
2坟募、改造實現(xiàn):
2.1? 對于前端功能界面不友好的問題岛蚤,改造時新添加了針對工程、模塊懈糯、配置項的基本搜索涤妒,以及對配置的批量修改功能、服務(wù)端配置推送功能(同步推送赚哗、異步補償)她紫、單server客戶端實時監(jiān)控等。下面給出兩張樣例圖:
在圖1界面中對各工程的配置進行統(tǒng)一的管理屿储、配置贿讹,支持批量配置及按module的維護進行推送任務(wù)的創(chuàng)建、消費够掠。圖2中顯示了某一臺server對外client端連接的基本情況民褂,同時也在第一列顯示了推送任務(wù)的消費狀態(tài),便于觀察任務(wù)消費情況。
2.2? 針對服務(wù)端的單點問題助赞,在架構(gòu)設(shè)計上新添加了zk集群买羞、HA來做前端的負載均衡工程、nginx代理雹食。下面來看一張當前的系統(tǒng)架構(gòu)圖:
從上圖中可以看出畜普,server端和client端采用netty進行通信,netty是一個十分優(yōu)秀的異步事件驅(qū)動的網(wǎng)絡(luò)通信框架(Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.)群叶,目前很多rpc的框架都采用它來通信吃挑,比如:hadoop rpc的avro,如果讀者對netty沒有接觸過或者不是很熟悉的話街立,建議參看官網(wǎng)netty.io或http://blog.csdn.net/zxhoo/article/details/17264263上的系列文章舶衬。客戶端可以主動從server端拉取自己的工程配置(大部分的配置中心的設(shè)計為在應(yīng)用啟動時拉取赎离,如果拉取不到或者client選擇不覆蓋則加載client端本地的配置文件)逛犹,服務(wù)端也可以主動向與此連接的客戶端推送配置(客戶端也可自由選擇是否接受服務(wù)端推送過來的配置)。client在連接一個server時梁剔,通過域名(不是ip)來連接虽画,可以通過nginx來做一定的負載及容災(zāi)(當然也可以通過服務(wù)端的服務(wù)心跳檢測來做)。client與server連接上后荣病,client端會對這個channel進行心跳檢測码撰,當channel失效時,會重新與server端建立連接个盆。
zk在當前架構(gòu)中需要擔任的角色是客戶端連接信息的存儲和推送任務(wù)的存儲脖岛,當客戶端連接上某一臺server時,會通過server向client進行注冊颊亮,其目的也是為了推送任務(wù)的創(chuàng)建柴梆;當用戶在配置管理界面對配置修改后绍在,通過創(chuàng)建對工程模塊下的配置推送任務(wù)件舵,及任務(wù)的成功消費來實現(xiàn)將修改后的配置推送至client合武。zk的客戶端選用的是curator,curator應(yīng)該是目前最好的zk的客戶端汤善,與zkClient比優(yōu)勢很多,它里面提供了對zk節(jié)點(也可包括子節(jié)點)結(jié)構(gòu)、信息變化的事件監(jiān)聽,事件的類型有創(chuàng)建、更新芯咧、刪除等。當推送任務(wù)被創(chuàng)建時會獲取到一條更新事件,然后根據(jù)該事件內(nèi)容已經(jīng)具體處理。
下面我們考慮一種情況闪金,當某臺server端由于發(fā)版或者其他原因囱嫩,突然重啟或宕機時恃疯,原先與之連接的client channel將全部失效,雖然通過client端的心跳檢測可以連接到另外的server上墨闲,但對于原先已經(jīng)創(chuàng)建好但沒有成功消費的推送任務(wù)怎么處理今妄?我們的處理方式是建立了一個job對這些任務(wù)進行異步推送補償。
該架構(gòu)上還有一個重點的點在圖中的map上鸳碧,map主要用來緩存應(yīng)用內(nèi)部與該server相連接的client信息蛙奖,用于推送任務(wù)的消費,客戶端的monitor是其次杆兵。
該架構(gòu)存在的不足或者不完善的地方有很多雁仲,就拿服務(wù)組的高可用而言就不是業(yè)界rpc調(diào)用的首選解決方案,另外也存在單點琐脏、單數(shù)據(jù)節(jié)點的問題攒砖、對與某一server group所有建立連接的client信息的統(tǒng)一監(jiān)控維護。下面對該架構(gòu)進行改進設(shè)想日裙,同時也將是下一步發(fā)展的方向吹艇。
新的架構(gòu)中改進的地方有:
(1)server的可用性通過向zk注冊來實現(xiàn)(臨時節(jié)點),client端在連接server或者當監(jiān)聽到server的節(jié)點失效時來再次維護本地server group緩存昂拂,實際連接時受神,直接從server group緩存中根據(jù)均衡算法獲取一條server ip即可。
(2)利用redis來進行server group全局的client信息的緩存格侯,便于對client的全局監(jiān)控及server group全局任務(wù)推送狀態(tài)的監(jiān)控維護鼻听。
(3)數(shù)據(jù)庫分庫分表(可按照project的屬性作為分庫的key,這一點可能并不是所有公司都需要联四,只是一個架構(gòu)設(shè)想撑碴,因為配置的數(shù)據(jù)與業(yè)務(wù)系統(tǒng)的數(shù)據(jù)比起來量少的太多),同時需要備庫來對主庫進行備份朝墩,提高可用性醉拓。
2.3? 對與上述協(xié)議的問題,需要根據(jù)各公司或者團隊的實際需求來調(diào)整收苏,并沒有一個統(tǒng)一的標準方案亿卤。
2.4? server group的配置數(shù)據(jù)安全問題也與2.3相似,實現(xiàn)方式還是需要根據(jù)各公司內(nèi)部的習(xí)慣來做鹿霸,可以通過白名單的方式排吴、也可通過認證簽名的方式、也可生產(chǎn)白名單其它環(huán)境認證簽名杜跷,如果是確定完全走內(nèi)網(wǎng)通信的話傍念,非生產(chǎn)環(huán)境也可不做安全限制矫夷。
2.5? 配置中心的配置修改后,client端需不需要重啟應(yīng)用來拉取新的配置完全依賴于client server的自身實現(xiàn)憋槐,可以不用重啟双藕,也可通過設(shè)置client端的配置來決定是否選擇覆蓋本地工程配置。
最后提醒一點:client端盡量不要對應(yīng)用配置做緩存阳仔,不然就配置中心就失去了意義忧陪,當然這里可以通過監(jiān)聽配置中心推送過來的配置變化來刷新緩存,不過個人認為完全沒有這樣的必要近范。