分布式配置中心(Nacos、Apollo)選型比較
因為公司進行系統(tǒng)的服務(wù)化拆分,導(dǎo)致模塊驟增,隨之而來配置文件管理難度也隨之增加,所以想采用一個配置集中管理的中間件。
下面對市面比較流行的Naocs和Apollo從各方面進行比較。

1. 配置中心
1.1 什么是配置
應(yīng)用程序在啟動和運行的時候往往需要讀取一些配置信息,配置基本上伴隨著應(yīng)用程序的整個生命周期,比如:數(shù) 據(jù)庫連接參數(shù)、啟動參數(shù)等。
配置主要有以下幾個特點:
- 配置是獨立于程序的只讀變量
配置對于程序是只讀的,程序通過讀取配置來改變自己的行為,但是程序不應(yīng)該去改變配置
- 配置伴隨應(yīng)用的整個生命周期
配置貫穿于應(yīng)用的整個生命周期,應(yīng)用在啟動時通過讀取配置來初始化,在運行時根據(jù)配置調(diào)整行為。
比如:啟動時需要讀取服務(wù)的端口號、系統(tǒng)在運行過程中需要讀取定時策略執(zhí)行定時任務(wù)等。
- 配置可以有多種加載方式
常見的有程序內(nèi)部hard code,配置文件,環(huán)境變量,啟動參數(shù),基于數(shù)據(jù)庫等
- 配置需要治理
同一份程序在不同的環(huán)境(開發(fā),測試,生產(chǎn))、不同的集群(如不同的數(shù)據(jù)中心)經(jīng)常需要有不同的配置,所以需要有完善的環(huán)境、集群配置管理
1.2 什么是配置中心
在分布式服務(wù)架構(gòu)中,當系統(tǒng)從一個單體應(yīng)用,被拆分成分布式系統(tǒng)上一個個服務(wù)節(jié)點后,配置文件也必須跟著遷移 (分割),這樣配置就分散了,不僅如此,分散中還包含著冗余,如下圖
而配置中心將配置從各應(yīng)用中剝離出來,對配置進行統(tǒng)一管理,應(yīng)用自身不需要自己去管理配置。如下圖

配置中心的服務(wù)流程如下:
1、用戶在配置中心發(fā)布、更新配置信息。
2、服務(wù)A和服務(wù)B及時得到配置更新通知,從配置中心獲取配置。
總得來說,配置中心就是一種統(tǒng)一管理各種應(yīng)用配置的基礎(chǔ)服務(wù)組件。
1.3 為什么需要配置中心
隨分布式微服務(wù)的發(fā)展,服務(wù)節(jié)點越來越多,配置問題逐漸顯現(xiàn)出來:
- 隨著程序功能的日益復(fù)雜,程序的配置日益增多,各種功能的開關(guān)、參數(shù)的配置、服務(wù)器的地址
- 大量模塊使用各自的配置,可能導(dǎo)致運維繁瑣、管理混亂、各個節(jié)點配置文件不一致
- 對配置的期望也越來越高,配置修改后實時生效,灰度發(fā)布, 版本管理 ,環(huán)境區(qū)分,完善的權(quán)限、審核機制等
在這樣的大環(huán)境下,傳統(tǒng)的通過配置文件、數(shù)據(jù)庫等方式已經(jīng)越來越無法滿足開發(fā)人員對配置管理的需求。
1.4 配置中心小結(jié)
總結(jié)一下,在傳統(tǒng)巨型單體應(yīng)用紛紛轉(zhuǎn)向分布式服務(wù)架構(gòu)的歷史進程中,配置中心是服務(wù)化不可缺少的一個系統(tǒng)組件,在這種背景下中心化的配置服務(wù)即配置中心應(yīng)運而生,一個合格的配置中心需要滿足如下特性:
- 配置項容易讀取和修改
- 分布式環(huán)境下應(yīng)用配置的可管理性,即提供遠程管理配置的能力
- 支持對配置的修改的檢視以把控風險
- 可以查看配置修改的歷史記錄
- 不同部署環(huán)境下應(yīng)用配置的隔離性
整個配置中心的作用系統(tǒng)運行時能夠動態(tài)調(diào)整程序的行為。
2. 開源配置中心介紹
目前市面流行的配置中心有:
- Disconf
2014年7月,百度開源的配置管理中心,同樣具備配置的管理能力,不過目前已經(jīng)不維護了 。
- Spring Cloud Config
2014年9月,Spring Cloud 開源生態(tài)組件,可以和Spring Cloud體系無縫整合,但依賴Git或SVN 。
- Apollo
2016年5月,攜程開源的配置管理中心,具備規(guī)范的權(quán)限、流程治理等特性。
- Nacos
2018年6月,阿里開源的配置中心,也可以做RPC的服務(wù)發(fā)現(xiàn)。
因Disconf不再維護,且Spring Cloud Config 需要依賴Git或SVN。所以只介紹下Apollo和Nacos
2.1 Nacos
Nacos包含的注冊中心+配置中心,以下只說配置中心。
2.1.1 簡介
Nacos 致力于幫助服務(wù)發(fā)現(xiàn)、配置和管理微服務(wù)。Nacos 提供了一組簡單易用的特性集,幫助您快速實現(xiàn)動態(tài)服務(wù)發(fā)現(xiàn)、服務(wù)配置、服務(wù)元數(shù)據(jù)及流量管理。
Nacos 更敏捷和容易地構(gòu)建、交付和管理微服務(wù)平臺。Nacos 是構(gòu)建以“服務(wù)”為中心的現(xiàn)代應(yīng)用架構(gòu) (例如微服務(wù)范式、云原生范式) 的服務(wù)基礎(chǔ)設(shè)施。
- Nacos文檔中心地址:https://nacos.io/zh-cn/docs/what-is-nacos.html
2.1.2 特性
Nacos 支持幾乎所有主流類型的服務(wù)發(fā)現(xiàn)、配置和管理,現(xiàn)只說Nacos的配置中心功能。
- 動態(tài)配置服務(wù)可以讓您以中心化、外部化和動態(tài)化的方式管理所有環(huán)境的應(yīng)用配置和服務(wù)配置。
- 動態(tài)配置消除了配置變更時重新部署應(yīng)用和服務(wù)的需要,讓配置管理變得更加高效和敏捷。
- 配置中心化管理讓實現(xiàn)無狀態(tài)服務(wù)變得更簡單,讓服務(wù)按需彈性擴展變得更容易。
- Nacos 提供了一個簡潔易用的UI幫助您管理所有的服務(wù)和應(yīng)用的配置。
- Nacos 還提供包括配置版本跟蹤、金絲雀發(fā)布、一鍵回滾配置以及客戶端配置更新狀態(tài)跟蹤在內(nèi)的一系列開箱即用的配置管理特性,幫助您更安全地在生產(chǎn)環(huán)境中管理配置變更和降低配置變更帶來的風險。
2.1.3 架構(gòu)
Nacos配置中心分為Server與Client,server采用Java編寫,為client提供配置服務(wù)。
Client可以用多語言實現(xiàn),Client與服務(wù)模塊嵌套在一起,Nacos提供SDK和OpenAPI,如果沒有SDK也可以根據(jù)OpenAPI手動寫服務(wù)注冊與發(fā)現(xiàn)和配置拉取的邏輯 。
配置中心架構(gòu)圖:

- 用戶通過Nacos Server的控制臺集中對多個服務(wù)的配置進行管理。
- 各服務(wù)統(tǒng)一從Nacos Server集群中獲取各自的配置,并監(jiān)聽配置的變化。
2.1.4 開發(fā)
Nacos配置中心支持與Spring、Spring Boot、Spring Cloud整合,通過xml或注解方式即可輕松實現(xiàn)。演示下與Spring項目進行整合。
1.服務(wù)端
控制臺發(fā)布配置截圖
- Nacos服務(wù)端增加useLocalCacheSwitch配置,用于控制是否使用緩存
- 發(fā)布配置
2.客戶端
- <dependency>
- <groupId>com.alibaba.nacos</groupId>
- <artifactId>nacos-client</artifactId>
- <version>1.4.1</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba.nacos</groupId>
- <artifactId>nacos-spring-context</artifactId>
- <version>1.0.0</version>
- </dependency>
- <!--NacosServer地址-->
- <nacos:global-properties server-addr="192.168.134.128:8848" />
- <!--在NacosServer配置的文件-->
- <nacos:property-source data-id="application.properties"
- group-id="redirectpaymentservice"
- auto-refreshed="true"/>
- @Service("Tx2101")
- public class Tx2101 extends TxBase {
- @NacosValue(value = "${useLocalCacheSwitch}", autoRefreshed = true)
- private boolean useLocalCacheSwitch;
- @Override
- public Document process(Document document) throws CodeException {
- System.out.println("是否刷新緩存:" + useLocalCacheSwitch);
- return null;
- }
- }
- 編寫java代碼,動態(tài)刷新配置
- applicationContext.xml增加NacosServer的相關(guān)配置
- pom.xml 增加nacos-client的依賴
3.效果
- 是否刷新緩存:false
- 是否刷新緩存:true
- 在Nacos服務(wù)端改變useLocalCacheSwitch的配置后,再次訪問2101接口,打印如下:
- 模塊啟動后訪問2101接口,打印如下:
2.1.5 灰度
Nacos服務(wù)端修改配置后,勾選Beat發(fā)布,指定IP地址,然后選擇發(fā)布Beta。

- 只有指定的IP節(jié)點的配置被更新
2.1.5 部署
在單機模式下,Nacos沒有任何依賴,默認使用內(nèi)嵌的數(shù)據(jù)庫作為存儲引擎,也可換成mysql;在集群模式下,Nacos依賴Mysql做存儲。
生產(chǎn)環(huán)境使用Nacos為了達到高可用不能使用單機模式,需要搭建nacos集群。
下圖是官方推薦的集群方案,通過域名 + VIP模式的方式來實現(xiàn)??蛻舳伺渲玫膎acos,當Nacos集群遷移時,客戶端配置無需修改。
集群部署架構(gòu)圖:
集群部署架構(gòu)圖
2.1.7 小結(jié)
Nacos使用簡單、部署方便、性能較高,能夠?qū)崿F(xiàn)基本的配置管理,提供的控制臺也非常簡潔。
但權(quán)限方面控制粒度較粗,且沒有審核機制。
2.2 Apollo
2.2.1 簡介
Apollo(阿波羅)是攜程框架部門研發(fā)的分布式配置中心,能夠集中化管理應(yīng)用的不同環(huán)境、不同集群的配置,配 置修改后能夠?qū)崟r推送到應(yīng)用端,并且具備規(guī)范的權(quán)限、流程治理等特性,適用于微服務(wù)配置管理場景。
Apollo包括服務(wù)端和客戶端兩部分:
服務(wù)端基于Spring Boot和Spring Cloud開發(fā),打包后可以直接運行,不需要額外安裝Tomcat等應(yīng)用容器。Java客戶端不依賴任何框架,能夠運行于所有Java運行時環(huán)境,同時對Spring/Spring Boot環(huán)境也有較好的支持。
- 文檔:https://github.com/ctripcorp/apollo/wiki。
2.2.2 特性
基于配置的特殊性,所以Apollo從設(shè)計之初就立志于成為一個有治理能力的配置發(fā)布平臺,目前提供了以下的特性:
- 統(tǒng)一管理不同環(huán)境、不同集群的配置
- 配置修改實時生效(熱發(fā)布)
- 版本發(fā)布管理
- 灰度發(fā)布
- 權(quán)限管理、發(fā)布審核、操作審計
- 客戶端配置信息監(jiān)控
- 提供Java和.Net原生客戶端
- 提供開放平臺API
- 部署簡單
2.2.3 架構(gòu)
Apollo架構(gòu)從外部和內(nèi)部進行分析
- 地址:https://ctripcorp.github.io/apollo/#/zh/design/apollo-design
基礎(chǔ)模型
如下即是Apollo的基礎(chǔ)模型:
- 用戶在配置中心對配置進行修改并發(fā)布
- 配置中心通知Apollo客戶端有配置更新
- Apollo客戶端從配置中心拉取最新的配置、更新本地配置并通知到應(yīng)用

2.2.4 開發(fā)
Apollo支持API方式和Spring整合方式 。
API方式靈活,功能完備,配置值實時更新(熱發(fā)布),支持所有Java環(huán)境。
Spring方式接入簡單,如
- 代碼中直接使用,如:@Value("${someKeyFromApollo:someDefaultValue}")
- 直接托管spring的配置,如在apollo中直接配置spring.datasource.url=jdbc:mysql://localhost:3306/somedb?characterEncoding=utf8
- Placeholder方式:
- Spring boot的@ConfigurationProperties方式
Spring方式也可以結(jié)合API方式使用,如注入Apollo的Config對象,就可以照常通過API方式獲取配置了
下面只介紹下Spring整合Apollo方式,做一個演示:
1.服務(wù)端

- 控制臺添加useLocalCacheSwitch配置,用于控制是否使用緩存
- 發(fā)布配置
2.客戶端
- <dependency>
- <groupId>com.ctrip.framework.apollo</groupId>
- <artifactId>apollo-client</artifactId>
- <version>1.1.0</version>
- </dependency>
- <apollo:config/>
- -Dapp.id=RedirectPaymentService -Denv=DEV -Ddev_meta=http://localhost:8080
- @Service("Tx2101")
- public class Tx2101 extends TxBase {
- @Value("${useLocalCacheSwitch:false}")
- private boolean useLocalCacheSwitch;
- @Override
- public Document process(Document document) throws CodeException {
- System.out.println("是否刷新緩存:" + useLocalCacheSwitch);
- return null;
- }
- }
- 編寫java代碼,動態(tài)刷新配置
- VM options啟動參數(shù)
- applicationContext.xml增加apollo相關(guān)配置
- pom.xml 增加apollo-client的依賴
3.效果
- 是否刷新緩存:false
- 是否刷新緩存:true
- 在Apollo控制臺改變useLocalCacheSwitch的配置后,再次訪問2101接口,打印如下:
- 模塊啟動后訪問2101接口,打印如下:
2.2.5 灰度
Apollo控制臺創(chuàng)建灰度版本,配置灰度規(guī)則,指定灰度的IP或AppID。

指定的IP節(jié)點或AppID模塊的配置被更新
2.2.6 部署
Apollo高可用架構(gòu)模塊的概覽 :

上圖簡要描述了Apollo的總體設(shè)計,我們可以從下往上看:
- Config Service提供配置的讀取、推送等功能,服務(wù)對象是Apollo客戶端
- Admin Service提供配置的修改、發(fā)布等功能,服務(wù)對象是Apollo Portal(管理界面)
- Config Service和Admin Service都是多實例、無狀態(tài)部署,所以需要將自己注冊到Eureka中并保持心跳
- 在Eureka之上我們架了一層Meta Server用于封裝Eureka的服務(wù)發(fā)現(xiàn)接口
- Client通過域名訪問Meta Server獲取Config Service服務(wù)列表(IP+Port),而后直接通過IP+Port訪問服務(wù),同時在Client側(cè)會做load balance、錯誤重試
- Portal通過域名訪問Meta Server獲取Admin Service服務(wù)列表(IP+Port),而后直接通過IP+Port訪問服務(wù),同時在Portal側(cè)會做load balance、錯誤重試
- 為了簡化部署,我們實際上會把Config Service、Eureka和Meta Server三個邏輯角色部署在同一個JVM進程中
2.2.7 小結(jié)
Apollo在配置管理流程上比較完善,相應(yīng)配置的發(fā)布審核、權(quán)限管理等、配置的繼承等,但Apollo需要使用人員進行簡單學習,存在學習成本。
Appollo部署較為復(fù)雜需要3個模塊同時工作,部署一套生產(chǎn)高可用集群至少需要7個節(jié)點。
3. 總結(jié)
3.1 功能比較
3.2 結(jié)論
從配置中心角度來看,性能方面Nacos的讀寫性能最高,Apollo次之;功能方面Apollo最為完善,但Nacos具有Apollo大部分配置管理功能。Nacos的一大優(yōu)勢是整合了注冊中心、配置中心功能,部署和操作相比 Apollo都要直觀簡單,因此它簡化了架構(gòu)復(fù)雜度,并減輕運維及部署工作。
總的來看,Apollo和Nacos生態(tài)支持都很廣泛,在配置管理流程上做的都很好。Apollo相對于Nacos在配置管理做的更加全面;Nacos則使用起來相對比較簡潔,在對性能要求比較高的大規(guī)模場景更適合。
對于公司目前來說,修改配置的次數(shù)不是特別的頻繁,對于配置權(quán)限的管理不是特別嚴格的,且對讀寫性能有一定要求的,可采用Nacos,反之使用Apollo。