本文已收錄 https://github.com/lkxiaolou/lkxiaolou 歡迎star。
配置中心
業務上的配置,功能開關,服務治理上對弱依賴的降級,甚至數據庫的密碼等,都可能用到動態配置中心。
在沒有專門的配置中心組件時,我們使用硬編碼、或配置文件、或數據庫、緩存等方式來解決問題。
硬編碼修改配置時需要重新編譯打包,配置文件需要重啟應用,數據庫受限於性能,緩存喪失了及時性。
可能都不完美,但能從中總結出配置中心的需求,相對來說還是比較明確:
- 能夠存儲、獲取並監聽配置(必須)
- 配置變更時能及時推送給監聽者(必須)
- 有一個可視化的查看變更配置的控制台(必須)
- 配置變更可灰度執行(加分)
- 配置變更可回滾(加分)
目前使用最多的配置中心可能是攜程開源的Apollo,還有Spring Cloud Config、阿里開源的Nacos、百度的Disconf等。
Nacos配置中心
Nacos
是Naming and Configuration Service
的縮寫,從名字上能看出它重點關注的兩個領域是Naming
即注冊中心和Configuration
配置中心。
本文講解nacos的配置中心的架構設計和實現原理,基於2.0.0
版本(注:2.0.0版本與1.x版本區別較大)
Nacos調試環境搭建
- 先從github上clone代碼(網速比較慢,加上--depth=1參數)
git clone --depth=1 https://github.com/alibaba/nacos.git
- 導入IDE,看代碼,調試更方便
- 啟動Server端:運行console模塊下的Nacos.main(),這個類掃描的路徑最廣,能啟動所有的模塊
-
JVM參數可帶上
-Dnacos.standalone=true -Dnacos.functionMode=config
,指定單機模式,且只啟動config模塊 -
--spring.config.additional-location=nacos/distribution/conf
,程序參數指定配置文件目錄 -
正常啟動,console打印出Ncos控制台地址,進入Nacos控制台,輸入用戶名密碼(默認均為nacos)即可登錄
-
- 使用client進行測試,example模塊下有configExample可進行config的測試,為了不動源代碼,可copy一份configExample進行修改測試
Nacos配置模型
namespace + group + dataId 唯一確定一個配置
- namespace:與client綁定,一個clinet對應到一個namespace,可用來隔離環境或區分租戶
- group:分組,區分業務
- dataId:配置的id
客戶端啟動流程
- 參數准備時,如果配置了nacos服務端地址,則直接使用;如果配置了endpoint,則從endpoint中獲取nacos服務端地址,這樣有個好處是服務端地址變更,擴縮容都無需重啟client,更詳細可參考
https://nacos.io/en-us/blog/namespace-endpoint-best-practices.html
- 在客戶端第一次與服務端交互時創建GRPC連接,隨機挑選一台server建立連接,后續都使用該連接,請求失敗都會有重試,針對請求級別也有限流;重試失敗或者服務端主動斷開連接,則會重新挑選一台server進行建鏈
請求模型
從gRPC的proto文件能看出請求與返回的定義比較統一
message Metadata {
string type = 3;
string clientIp = 8;
map<string, string> headers = 7;
}
message Payload {
Metadata metadata = 2;
google.protobuf.Any body = 3;
}
service Request {
// Sends a commonRequest
rpc request (Payload) returns (Payload) {
}
}
- type是請求/返回類的類名
- clientIp是客戶端ip
- headers是攜帶的header信息
- Playload中的body以json格式編碼
在com.alibaba.nacos.api.config.ConfigService
中可以找到所有配置中心能使用的接口
重點關注這幾個接口:
- getConfig:讀取配置
- publishConfig:發布配置
- publishConfigCas:原子的發布配置,若有被其他線程變更則發布失敗,類似java中的CAS
- removeConfig:刪除配置
- addListener:監聽配置
- removeListener:移除配置的監聽
變更推送
采取推拉結合的方式,既保證時效性,又保證數據一致性
數據存儲
Nacos配置中心的數據存儲支持內嵌的derby
數據庫,也支持外部數據庫mysql
,內嵌數據庫主要是為了單機測試時使用。
其中上文提及的publishConfigCas
的實現是利用了數據庫update ${table} set ${xx}=${zz} where md5=${old_md5}
來實現,如果已經這條數據被變更,則這次publish會失敗。
灰度和回滾
當勾選灰度發布時可填寫灰度的ip進行推送,不在灰度列表內的ip則不會接受到變更推送,並且灰度和正式是區分開的。
灰度的實現是記錄下了每次的發布,回滾到指定版本即可。
結語
本文從背景出發,結合Nacos配置中心的各個重要模塊進行了一一解釋,能夠從整體上對Nacos的配置中心有一個把握。期望后續能對Nacos注冊中心進行分析介紹。
搜索關注微信公眾號"捉蟲大師",后端技術分享,架構設計、性能優化、源碼閱讀、問題排查、踩坑實踐。