轉載公衆号:java後端技術

一、前言
對于配置檔案,我們并不陌生,它提供我們可以動态修改程式運作能力。引用别人的一句話就是:
系統運作時(runtime)飛行姿态的動态調整!
我可以把我們的工作稱之為在快速飛行的飛機上修理零件。我們人類總是無法掌控和預知一切。對于我們系統來說,我們總是需要預留一些控制線條,以便在我們需要的時候做出調整,控制系統方向(如灰階控制、限流調整),這對于擁抱變化的網際網路行業尤為重要。
對于單機版,我們稱之為配置(檔案);對于分布式叢集系統,我們稱之為配置中心(系統);
二、為什麼要有分布式配置中心
1、項目背景
我們現在有一個項目,使用SSM進行開發的,配置檔案的話我們知道是一個叫做application.properties的檔案。
我們也知道這個配置檔案會在項目啟動的時候被加載到記憶體中進行使用的。
2、需求一
由于業務的變動,使用者在以前進行注冊的時候預設的使用者名是“小強”,但是新的上司來了,需要把這個改成“小明”。因為,業務的流量還是比較大的,是以,沒有辦法在白天流量高峰期修改配置檔案,進行重新開機!
此時,就辛苦開發的小哥了,他們需要等到半夜裡淩晨三四點的時候,沒有流量的時候,小心翼翼的去修改application.properties配置檔案,必将系統進行重新開機。
另外,公司采用的是叢集,進行了負載均衡,系統部署在了多台伺服器上,那麼開發小哥需要一台台的進行修改,小心翼翼的進行修改,生怕出了一點意外!
開發小哥是在忍受不了這種變更了,修改一個配置就需要如此周折的去完成這件事情!忍無可忍,于是像交流群裡的一位大神請教,大神指點讓他去搜尋一下“分布式配置中心”。
3、需求二
我們在進行業務開發的時候,一般會有多個環境,至少應該有三個:開發、測試、線上。那這三個環境之間的配置檔案肯定是有不同的,比如說他們之間的資料庫是肯定不同的!application.properties例如:
那我們如何使不同環境之間進行隔離哪?答案很簡單,不就是指定三個不同的檔案,然後在項目啟動的時候指定不同的環境不就行了嗎?于是開發小哥就動起來了,修改如下:
修改之後,運維的小哥不願意了!因為,一開始沒有進行環境隔離的時候,隻有一個環境(開發完成之後,直接修改配置檔案,合并到主幹,線上釋出),運維小哥在使用Jenkins+Git+Maven進行自動化內建的時候,隻需要配置一下就行了!在Jenkins啟動的腳本指令是:java -jar ssm.jar 就可以搞定了,經開發小哥這樣一搞,修改啟動的指令不說,新增了環境,還要為他們建立不同環境的自動化內建。
分别需要設定的指令如下:
運維小哥的工作量直接翻了一倍多,想想還有十幾個項目需要這樣進行修改,運維小哥悄悄的拿起了抽屜裡準備了很久的xxx走向了開發小哥。
4、到底什麼是分布式配置中心
從上邊的兩個小需求,我們已經可以看出來,傳統配置的方式已經暴露出了很多問題,其他的諸如:曆史版本管理,權限控制,安全性等等問題,是傳統的配置檔案無法解決的!
随着業務的發展、微服務架構的更新,服務的數量、程式的配置日益增多(各種微服務、各種伺服器位址、各種參數),傳統的配置檔案方式和資料庫的方式已無法滿足開發人員對配置管理的要求:
安全性:配置跟随源代碼儲存在代碼庫中,容易造成配置洩漏;
時效性:修改配置,需要重新開機服務才能生效;
局限性:無法支援動态調整:例如日志開關、功能開關;
是以,我們需要配置中心來統一管理配置!把業務開發者從複雜以及繁瑣的配置中解脫出來,隻需專注于業務代碼本身,進而能夠顯著提升開發以及運維效率。同時将配置和釋出包解藕也進一步提升釋出的成功率,并為運維的細力度管控、應急處理等提供強有力的支援。
三、配置的一步步演進
當我們是一個單機服務的是,我們的配置通常寫在一個檔案中的,代碼釋出的時候,把配置檔案和程式推送到機器上去。
1、單機配置檔案
當随着業務的使用者量增加,通常我們會把我們的服務進行多機器(叢集)部署。這時候,配置的釋出就變成了如下:
2、多機器配置
行,這樣發配置也能接受,業務的急劇擴張,導緻單機服務無法滿業務需求。這時候需要對單體大服務進行切開,服務走向SOA(微服務化)。
3、分布式叢集部署配置檔案
這樣去部署配置簡直是一場噩夢,而且無法做到快速的動态的調整。失去了配置主要意義之一。這時候就需要今天說的統一配置中心。
三、一個簡版的配置中心是什麼樣的
1、配置中心的特點
配置的增删改查;
不同環境配置隔離(開發、測試、預釋出、灰階/線上);
高性能、高可用性;
請求量多、高并發;
讀多寫少;
2、簡版配置系統
我們可以設計出如下的簡版配置中心:
設計說明點:
通過OA系統對每一條配置(每一個配置有唯一的配置ID)進行增删改查;
區分不同環境的配置,每個環境同一配置ID對應不同資料庫記錄;
配置最終以json格式(便于編輯和了解)儲存在mysql資料庫中;
引入redis叢集,做配置的緩存(比如可以設定配置修改後1分鐘後生效);
配置對外服務,多機器部署,滿足性能需要;
如果有必要,可以引入配置曆史修改記錄;
很多時候,這樣可以基本上滿足我們對配置系統的基本需求,對配置的增删改查,能容忍一段時間的資料不一緻性。
這種設計,由于所有的配置都存放在集中式緩存中,這樣集中式的緩存也會有他的性能瓶頸。而且,每次配置的通路都需要發起rpc請求(網絡請求),是以考慮在用戶端引入本地緩存(localCache,例如Ehcache)。
四、簡版基礎上的一些改進
1、配置中心之性能可用性改進
考慮到,減少網絡請求的因素,在用戶端引入localcache,來解決系統的高可用,高性能、可伸縮性。本地緩存配置中心如下:
相對于第一版的改進點是,在用戶端引入localcache。開啟線程異步調用配置服務,更新本地配置。
這樣可以減少rpc調用。
基于資料的CAP原理,該方式隻做到了AP,這裡會存在資料的一段時間的不一緻性,但最終會保證是配置的最終一緻性。如何解決這個資料不一緻性問題?
2、配置中心之資料一緻性改進
還好,配置通常都隻會有一個入口修改,是以可以考慮在配置修改後,通知應用服務清理本地緩存和分布式緩存。這裡可以引入mq或ZooKeeper。
最後通過,推拉相結合的方式,完成資料的一緻性。
六、開源項目
關于分布式配置中心,網上已經有很多開源的解決方案,例如:
1、Apollo
Apollo(阿波羅)是攜程架構部門研發的分布式配置中心,能夠集中化管理應用不同環境、不同叢集的配置,配置修改後能夠實時推送到應用端,并且具備規範的權限、流程治理等特性,适用于微服務配置管理場景。
項目位址:https://github.com/ctripcorp/apollo
2、XDiamond
全局配置中心,存儲應用的配置項,解決配置混亂分散的問題。名字來源于淘寶的開源項目Diamond,前面加上一個字母X以示差別。
項目位址:https://github.com/hengyunabc/xdiamond
3、Qconf
QConf 是一個分布式配置管理工具。 用來替代傳統的配置檔案,使得配置資訊和程式代碼分離,同時配置變化能夠實時同步到用戶端,而且保證使用者高效讀取配置,這使的工程師從瑣碎的配置修改、代碼送出、配置上線流程中解放出來,極大地簡化了配置管理工作。
項目位址:https://github.com/Qihoo360/QConf
4、Disconf
專注于各種「分布式系統配置管理」的「通用元件」和「通用平台」, 提供統一的「配置管理服務」包括 百度、滴滴出行、銀聯、網易、拉勾網、蘇甯易購、順豐科技 等知名網際網路公司正在使用!「disconf」在「2015 年度新增開源軟體排名 TOP 100(OSC開源中國提供)」中排名第16強。Disconf的功能特點描述圖:
項目位址:https://github.com/knightliao/disconf
5、Spring Cloud Config
Spring Cloud Config為分布式系統中的外部配置提供伺服器和用戶端支援。
項目位址:https://github.com/spring-cloud/spring-cloud-config
6、主要差別