Hi,好久不見,我是你們的walking****,在這個高燃BGM下又和大家見面了??。今天分享一個分布式、微服務(wù)架構(gòu)中重要的一個組件:配置中心。
也許你們現(xiàn)在的項目不是分布式、微服務(wù)架構(gòu),沒有用到配置中心,也沒聽說過配置中心,對它完全很陌生,那你就很有必要閱讀本文了。
本文將從
1)什么是配置、什么是配置中心以及配置中心的誕生講起,
2)然后簡單介紹幾個不錯的開源配置中心產(chǎn)品,
3)接著會重點介紹攜程開源的分布式配置中心Apollo的架構(gòu)以及基本的搭建與使用。
好了廢話不多說,開始...????
什么是配置?
眾所周知,應(yīng)用程序在啟動和運行的時候會去讀取一些「配置信息」,比如:數(shù)據(jù)庫連接參數(shù)、啟動參數(shù)、接口的超時時間、應(yīng)用程序的端口等?!概渲谩梗旧习殡S著應(yīng)用程序的整個生命周期。
不知道大家有沒有注意,配置其實它有一些比較明顯的特點,如下:
1、獨立于程序的只讀變量
1)配置是獨立于應(yīng)用程序的,并且同一個程序在不同的配置下會有不同的行為;
2)其次,配置對于程序是只讀的,程序通過讀取配置來改變自己的行為,程序不應(yīng)該去改變配置
2、伴隨應(yīng)用的整個生命周期
1)配置貫穿于應(yīng)用的整個生命周期,包括啟動和運行。應(yīng)用在啟動時通過讀取配置來初始化,在運行時根據(jù)配置調(diào)整行為。比如:啟動時需要讀取服務(wù)的端口號、系統(tǒng)在運行過程中需要讀取定時策略執(zhí)行定時任務(wù)、根據(jù)配置調(diào)整日志級別等。
3、多種加載方式
1)常見的加載方式有程序內(nèi)部硬編碼、配置文件、環(huán)境變量、啟動參數(shù)、基于數(shù)據(jù)庫等,最常用的是配置文件和環(huán)境變量這兩種方式。
4、需要治理
1)權(quán)限控制:由于配置能改變程序的行為,不正確的配置甚至?xí)斐蔀?zāi)難,所以對配置的修改必須有比較完善的權(quán)限控制體系來治理;
2)對不同環(huán)境、集群進行配置管理:同一個程序在不同的環(huán)境(開發(fā),測試,預(yù)生產(chǎn)、生產(chǎn))、不同的集群(如不同的數(shù)據(jù)中心、服務(wù)器在全國很多地方都有機房部署集群的情況)經(jīng)常需要有不同的配置,所以需要有完善的環(huán)境、集群配置管理的能力。
5、支持持久化
1)配置信息需要支持持久化,永久保存,重啟后依然能夠找到之前的配置,配置一旦生成就永久存在除非人為的刪除。
我們最常用的就是在項目的resources下創(chuàng)建各種properties文件放我們的各種配置
配置中心的誕生
配置中心的誕生和項目架構(gòu)的演進有著密切的聯(lián)系。傳統(tǒng)單體應(yīng)用存在一些潛在缺陷,如隨著規(guī)模的擴大,部署效率降低,團隊協(xié)作效率差,系統(tǒng)可靠性變差,維護困難,新功能上線周期長等,所以迫切需要一種新的架構(gòu)去解決這些問題,而微服務(wù)( microservices )架構(gòu)正是當(dāng)下一種流行的解決方案。
不過,解決一個問題的同時,往往會面臨很多新的問題,所以微服務(wù)化的過程中伴隨著很多的挑戰(zhàn),其中一個挑戰(zhàn)就是有關(guān)服務(wù)(應(yīng)用)配置的。
1)當(dāng)系統(tǒng)從一個單體應(yīng)用,被拆分成分布式系統(tǒng)上一個個服務(wù)節(jié)點后,配置文件也必須跟著遷移(分割),這樣配置就分散了,各個服務(wù)都有自己的配置,隨著項目需求的不斷壯大發(fā)展,配置會越來越多,到最后繁瑣的配置文件會讓你越來越崩潰,稍不注意出個錯配置錯了就得修改配置重新打包部署,特別麻煩。
2)在集群部署的情況下,如果新版本的配置會給系統(tǒng)帶來很大的影響,我們往往會選擇灰度發(fā)布,即先發(fā)布部分服務(wù)器,進行測試,穩(wěn)定后再將配置同步到所有服務(wù)器,如果說還用傳統(tǒng)的方式,那么我們就需要將配置文件一個個的修改然后重啟服務(wù),雖然不需要我們開發(fā)自己去做,有運維,那也挺煩人的,運維發(fā)布完了,我們還得檢查他改的是不是正確,費時費力。
3)而且在系統(tǒng)不斷的迭代的過程中有些配置在多個服務(wù)之間都是相同或相近的,就會有很大的冗余。
所以在分布式、微服務(wù)這種大環(huán)境下,傳統(tǒng)的項目配置方式的弊端就慢慢的凸顯出來了,這個問題變得非常棘手,亟待一種管理配置、治理配置的解決方案。這時,配置中心就應(yīng)運而生了。
什么是配置中心
配置中心,顧名思義,將配置中心化,說白了就是將配置從應(yīng)用中抽取出來,統(tǒng)一管理,優(yōu)雅的解決了配置的動態(tài)變更、權(quán)限管理、持久化、運維成本等問題。應(yīng)用程序自身只是從配置中心拿到自己想要的配置,既不需要去添加管理配置的接口,也不需要自己去實現(xiàn)配置的持久化,更不需要去關(guān)心配置何時變化。配置與應(yīng)用程序隔離開,單獨管理配置。
總得來說,配置中心就是一種統(tǒng)一管理各種應(yīng)用配置的基礎(chǔ)服務(wù)組件。
在系統(tǒng)架構(gòu)中,配置中心是整個微服務(wù)基礎(chǔ)架構(gòu)體系中的一個組件,如下圖,它的功能看上去并不起眼,無非就是配置的管理和存取,但它是整個微服務(wù)架構(gòu)中不可或缺的一環(huán)。
集中管理配置,那么就要將應(yīng)用的配置作為一個單獨的服務(wù)抽離出來了,同理也需要解決新的問題,比如:版本管理(為了支持回滾),權(quán)限管理等。
總結(jié)一下,在傳統(tǒng)巨型單體應(yīng)用紛紛轉(zhuǎn)向細粒度微服務(wù)架構(gòu)的歷史進程中,配置中心是微服務(wù)化不可缺少的一個系統(tǒng)組件,在這種背景下中心化的配置服務(wù)即配置中心應(yīng)運而生,一個合格的配置中心需要滿足一下功能:
對配置項的讀取和修改提供簡單易用的API和操作界面
添加新配置要夠簡單、直接、方便
支持不同管理員對配置的修改的不同權(quán)限,以把控風(fēng)險
可以查看配置修改的歷史記錄,以便回滾
不同部署環(huán)境相互隔離,互不影響
主流配置中心簡介
目前市面上用的比較多的配置中心有:(按開源時間排序)
簡介
1、Disconf
2014年7月百度開源的配置管理中心,專注于各種「分布式系統(tǒng)配置管理」的「通用組件」和「通用平臺」, 提供統(tǒng)一的「配置管理服務(wù)」。目前已經(jīng)不再維護更新。
https://github.com/knightliao/disconf
2、Spring Cloud Config
2014年9月開源,Spring Cloud 生態(tài)組件,可以和Spring Cloud體系無縫整合。
https://github.com/spring-cloud/spring-cloud-config
3、Apollo
2016年5月,攜程開源的配置管理中心,能夠集中化管理應(yīng)用不同環(huán)境、不同集群的配置,配置修改后能夠?qū)崟r推送到應(yīng)用端,并且具備規(guī)范的權(quán)限、流程治理等特性,適用于微服務(wù)配置管理場景。
https://github.com/ctripcorp/apollo
4、Nacos
2018年6月,阿里開源的配置中心,也可以做DNS和RPC的服務(wù)發(fā)現(xiàn)。
https://github.com/alibaba/nacos
功能特性對比
由于Disconf不再維護,下面主要對比一下Spring Cloud Config、Apollo和Nacos。

總的來看,Apollo和Nacos相對于Spring Cloud Config的生態(tài)支持更廣,在配置管理流程上做的更好。Apollo相對于Nacos在配置管理做的更加全面,Nacos則使用起來相對比較簡潔,在對性能要求比較高的大規(guī)模場景更適合。但對于一個開源項目的選型,項目上的人力投入(迭代進度、文檔的完整性)、社區(qū)的活躍度(issue的數(shù)量和解決速度、Contributor數(shù)量、社群的交流頻次等),這些因素也比較關(guān)鍵,考慮到Nacos開源時間不長和社區(qū)活躍度,所以從目前來看Apollo應(yīng)該是最合適的配置中心選型。
Apollo
Apollo特性
基于配置的特殊性,所以Apollo從設(shè)計之初就立志于成為一個有治理能力的配置發(fā)布平臺,目前提供了以下的特性:
1、統(tǒng)一管理不同環(huán)境、不同集群的配置
Apollo提供了一個統(tǒng)一界面集中式管理不同環(huán)境(environment)、不同集群(cluster)、不同命名空間(namespace)的配置。
同一份代碼部署在不同的集群,可以有不同的配置,比如zookeeper的地址等
通過命名空間(namespace)可以很方便地支持多個不同應(yīng)用共享同一份配置,同時還允許應(yīng)用對共享的配置進行覆蓋
2、配置修改實時生效(熱發(fā)布)
- 用戶在Apollo修改完配置并發(fā)布后,客戶端能實時(1秒)接收到最新的配置,并通知到應(yīng)用程序
3、版本發(fā)布管理
- 所有的配置發(fā)布都有版本概念,從而可以方便地支持配置的回滾
4、灰度發(fā)布
- 支持配置的灰度發(fā)布,比如點了發(fā)布后,只對部分應(yīng)用實例生效,等觀察一段時間沒問題后再推給所有應(yīng)用實例
5、權(quán)限管理、發(fā)布審核、操作審計
應(yīng)用和配置的管理都有完善的權(quán)限管理機制,對配置的管理還分為了編輯和發(fā)布兩個環(huán)節(jié),從而減少人為的錯誤。
所有的操作都有審計日志,可以方便地追蹤問題
6、客戶端配置信息監(jiān)控
- 可以在界面上方便地看到配置在被哪些實例使用
7、提供Java和.Net原生客戶端
提供了Java和.Net的原生客戶端,方便應(yīng)用集成
支持Spring Placeholder, Annotation和Spring Boot的ConfigurationProperties,方便應(yīng)用使用(需要Spring 3.1.1+)
同時提供了Http接口,非Java和.Net應(yīng)用也可以方便地使用
8、提供開放平臺API
Apollo自身提供了比較完善的統(tǒng)一配置管理界面,支持多環(huán)境、多數(shù)據(jù)中心配置管理、權(quán)限、流程治理等特性。不過Apollo出于通用性考慮,不會對配置的修改做過多限制,只要符合基本的格式就能保存,不會針對不同的配置值進行針對性的校驗,如數(shù)據(jù)庫用戶名、密碼,Redis服務(wù)地址等
對于這類應(yīng)用配置,Apollo支持應(yīng)用方通過開放平臺API在Apollo進行配置的修改和發(fā)布,并且具備完善的授權(quán)和權(quán)限控制
執(zhí)行流程
先來看一個簡單的工作流程圖,如下:
操作流程如下:
1、管理員通過可視化操作界面在Apollo配置中心修改、發(fā)布配置
2、應(yīng)用程序通過Apollo客戶端從配置中心拉取配置信息
管理員通過Apollo配置中心修改或發(fā)布配置后,會有兩種機制來保證應(yīng)用程序獲取最新配置:
1)Apollo配置中心主動向客戶端推送最新的配置;
2)Apollo客戶端會定時從Apollo配置中心拉取最新的配置。
通過以上推、拉的兩種機制共同來保證應(yīng)用程序能及時獲取到配置。
Apollo的安裝部署
下載地址:https://github.com/ctripcorp/apollo/releases
兩種下載方式,一是直接下載上圖的畫框的三個分別是adminservice、configservice、portal;二是下載source code源碼自己打包,zip 和 tar.gz 都可以。這里使用的第二種方式。
解釋一下為啥第一種下載方式會有三個包,這其實和Apollo的架構(gòu)有關(guān)。portal 是一個可視化界面會調(diào)用 adminservice 進行配置管理和發(fā)布,可以認為是 adminservice 的 client 端;configservice 和 Apollo 的 client 保持長連接,configservice 服務(wù)于 Apollo client 進行配置獲取,configservice 和 client 通過一種推拉結(jié)合的方式,實現(xiàn)配置實時更新的同時,保證配置更新不丟失。所以不管是第一種方式還是第二種方式,我們都需要運行三個jar程序。
采用第二種方式,下載好源碼并解壓后倒導(dǎo)入idea,如下

然后找到scripts文件夾并打開,有一個 sql 文件夾,里面有兩個 SQL 文件

?
在mysql里執(zhí)行這兩個SQL 文件,成功后會創(chuàng)建兩個數(shù)據(jù)庫

?
然后注意到 scripts 目錄下有兩個文件,build.bat 和 build.sh 文件,分別是Windows 和 linux用的。
需要打開對應(yīng)的文件更改一些參數(shù),如數(shù)據(jù)庫配置參數(shù)URL,用戶名密碼,改成你自己的。
下面這些是Erueka的不同環(huán)境的地址,我們就本地dev的不用改了
set dev_meta="http://localhost:8080"
set fat_meta="http://someIp:8080"
set uat_meta="http://anotherIp:8080"
set pro_meta="http://yetAnotherIp:8080"

然后,運行就直接就是用maven打包了,打完之后在各自的target目錄下即可看到

?

?

?
我是把這三個jar復(fù)制出來,放到一個專門的目錄,方便運行。
然后,依次啟動三個jar
java -jar apollo-configservice-1.6.1.jar
java -jar apollo-adminservice-1.6.1.jar
java -jar apollo-portal-1.6.1.jar

都啟動后,訪問http://localhost:8070/ 進入Apollo的配置管理中心,可以創(chuàng)建項目(walking是我自己創(chuàng)建的),稍后再講
然后訪問 http://localhost:8080/ 出現(xiàn)如下畫面,Apollo安裝部署成功。
創(chuàng)建項目
點擊創(chuàng)建項目,選擇部門,Apollo默認的有兩個樣例,當(dāng)然你可以在右上角管理員工具里添加,稍后再說。
然后填寫AppId,這是全局唯一的,客戶端調(diào)用的時候要用這個。應(yīng)用名稱就隨意寫了。
應(yīng)用負責(zé)人,默認的是Apollo,也可以在右上角管理員工具里增加。
項目管理員,可以額外添加該項目的管理員
然后提交就行了。
然后就會進入到該項目,默認會有一個application 的命名空間
可以添加命名空間
我們可以點擊新增配置來添加參數(shù)
新添加的參數(shù)是未發(fā)布狀態(tài),可點擊發(fā)布按鈕使其生效
然后就發(fā)布成功了。
Apollo工作原理
下圖是Apollo架構(gòu)模塊的概覽
各模塊職責(zé)
上圖簡要描述了Apollo的總體設(shè)計,我們可以從下往上看:
Config Service提供配置的讀取、推送等功能,服務(wù)對象是Apollo客戶端
Admin Service提供配置的修改、發(fā)布等功能,服務(wù)對象是Apollo Portal(管理界面)
Eureka提供服務(wù)注冊和發(fā)現(xiàn),為了簡單起見,目前Eureka在部署時和Config Service是在一個JVM進程中的
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進程中
分步執(zhí)行流程
Apollo啟動后,Config/Admin Service會自動注冊到Eureka服務(wù)注冊中心,并定期發(fā)送?;钚奶?/p>
Apollo Client和Portal管理端通過配置的Meta Server的域名地址經(jīng)由Software Load Balancer(軟件負載均衡器)進行負載均衡后分配到某一個Meta Server
Meta Server從Eureka獲取Config Service和Admin Service的服務(wù)信息,相當(dāng)于是一個Eureka Client
Meta Server獲取Config Service和Admin Service(IP+Port)失敗后會進行重試
獲取到正確的Config Service和Admin Service的服務(wù)信息后,Apollo Client通過Config Service為應(yīng)用提供配置獲取、實時更新等功能;Apollo Portal管理端通過Admin Service提供配置新增、修改、發(fā)布等功能
核心概念
application (應(yīng)用)
這個很好理解,就是實際使用配置的應(yīng)用,Apollo客戶端在運行時需要知道當(dāng)前應(yīng)用是誰,從而可以去獲取對應(yīng)的配置
關(guān)鍵字:appId
environment (環(huán)境)
配置對應(yīng)的環(huán)境,Apollo客戶端在運行時需要知道當(dāng)前應(yīng)用處于哪個環(huán)境,從而可以去獲取應(yīng)用的配置
關(guān)鍵字:env
cluster (集群)
一個應(yīng)用下不同實例的分組,比如典型的可以按照數(shù)據(jù)中心分,把上海機房的應(yīng)用實例分為一個集群,把北京機房的應(yīng)用實例分為另一個集群。
關(guān)鍵字:cluster
namespace (命名空間)
一個應(yīng)用下不同配置的分組,可以簡單地把namespace類比為文件,不同類型的配置存放在不同的文件中,如數(shù)據(jù)庫配置文件,RPC配置文件,應(yīng)用自身的配置文件等
關(guān)鍵字:namespaces
它們的關(guān)系如下圖所示:
?
Spring Boot整合Apollo
Apollo搭建好之后,我們通過一個簡單的SpringBoot項目來去從它上面獲取配置,進行一個測試。
入門案例
1、添加Apollo client依賴
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo.client.version}</version>
</dependency>

2、application.yml添加配置
server:
port: 8761
app:
id: walking #AppId是應(yīng)用的身份信息,是配置中心獲取配置的一個重要信息
apollo:
meta: http://localhost:8080 #eureka地址
bootstrap:
enabled: true #在應(yīng)用啟動階段,向Spring容器注入被托管的application.properties文件的配置信息
3、啟動類上增加 @EnableApolloConfig 注解
@RestController
public class ApolloController {
@Value("${test_key}")
String testApollo;
@GetMapping("testApollo")
public Map<String,Object> testApollo() {
Map<String,Object> result = new HashMap<>();
result.put("testApollo",testApollo);
return result;
}
}
4、訪問接口,拿到了配置value值
?
訪問多個命名空間
1、修改application.yml,增加 namespaces 選項,填寫命名空間名稱,application可以不用寫。
server:
port: 8761
app:
id: walking #AppId是應(yīng)用的身份信息,是配置中心獲取配置的一個重要信息
apollo:
meta: http://localhost:8080 #eureka地址
bootstrap:
enabled: true #在應(yīng)用啟動階段,向Spring容器注入被托管的application.properties文件的配置信息
namespaces: TEST1.datasource-mysql.config
2、獲取另外一個命名空間內(nèi)的參數(shù) mysql.url
@RestController
public class ApolloController {
@Value("${test_key}")
String testApollo;
@Value("${mysql.url}")
String mysqlUrl;
@GetMapping("testApollo")
public Map<String,Object> testApollo() {
Map<String,Object> result = new HashMap<String,Object>();
result.put("testApollo",testApollo);
result.put("mysqlUrl",mysqlUrl);
return result;
}
}
3、測試,拿到了
動態(tài)修改日志級別
日志模塊是每個項目中必須的,用來記錄程序運行中的相關(guān)信息。一般在開發(fā)環(huán)境下使用DEBUG級別的日志輸出,為了方便查看問題,而在線上一般都使用INFO或者ERROR級別的日志,主要記錄業(yè)務(wù)操作或者錯誤的日志。
那么問題來了,當(dāng)線上環(huán)境出現(xiàn)問題希望輸出DEBUG日志信息輔助排查的時候怎么辦呢?以前確實是這么做的:修改配置文件,重新打包然后上傳重啟線上環(huán)境。很麻煩,也很慢。
所以我們想通過把日志級別參數(shù)部署到 Apollo 上,然后監(jiān)聽參數(shù)變化后從 Apollo 上獲取日志級別,再修改日志級別,來達到熱更新的效果。
1、引入日志包,這里使用的是lombok,比較方便演示
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
2、application.yml???????
server:
port: 8761
app:
id: walking #AppId是應(yīng)用的身份信息,是配置中心獲取配置的一個重要信息
apollo:
meta: http://localhost:8080
bootstrap:
enabled: true #在應(yīng)用啟動階段,向Spring容器注入被托管的application.properties文件的配置信息。
namespaces: TEST1.datasource-mysql.config
eagerLoad:
enabled: true #將Apollo配置的加載提到初始化日志系統(tǒng)之前
logging:
level:
com:
walking:
controller: info #根據(jù)包名調(diào)整controller包的日志級別,為了后面演示在配置中心動態(tài)配置日志級別
3、增加了如下配置,用于將 Apollo 配置的加載提到初始化日志系統(tǒng)之前,以及配置com.walking.controller包的日志級別為 debug
eagerLoad:
enabled: true #將Apollo配置的加載提到初始化日志系統(tǒng)之前
logging:
level:
com:
walking:
controller: debug #根據(jù)包名調(diào)整controller包的日志級別,為了后面演示在配置中心動態(tài)配置日志級別
4、然后增加這樣一個參數(shù)用于部署日志級別
5、然后通過@ApolloConfigChangeListener注解監(jiān)聽配置的變化,監(jiān)聽到配置變化時重新設(shè)置該目錄的日志級別???????
@Slf4j
@Configuration
public class LoggerConfig {
private static final String LOGGER_TAG = "logging.level.";
@Autowired
private LoggingSystem loggingSystem;
/*
* 將Apollo服務(wù)端的中的配置注入這個類中。
*/
@ApolloConfig
private Config config;
/*
* @ApolloConfigChangeListener
* value 指定監(jiān)聽哪個 namespace,默認是 application
* interestedKeys 指定監(jiān)聽哪些key 如interestedKeys={"abc","123"},
* interestedKeyPrefixes 指定監(jiān)聽的key(模糊匹配)
* 監(jiān)聽配置中心配置的更新事件,若該事件發(fā)生,則調(diào)用refreshLoggingLevels方法,處理該事件。
* ConfigChangeEvent參數(shù):可以獲取被修改配置項的key集合,以及被修改配置項的新值、舊值和修改類型等信息。
*/
@ApolloConfigChangeListener(value="application",interestedKeyPrefixes = {LOGGER_TAG})
private void configChangeListter(ConfigChangeEvent changeEvent) {
refreshLoggingLevels(changeEvent);
}
private void refreshLoggingLevels(ConfigChangeEvent changeEvent) {
log.info("apollo config changed,LoggerConfig 更新日志級別");
Set<String> keyNames = changeEvent.changedKeys();
for (String key : keyNames) {
if (StringUtils.containsIgnoreCase(key, LOGGER_TAG)) {
ConfigChange change = changeEvent.getChange(key);
String newLevel = change.getNewValue();
String oldLevel = change.getOldValue();
LogLevel level = LogLevel.valueOf(newLevel.toUpperCase());
String packageName = key.replace(LOGGER_TAG, "");
loggingSystem.setLogLevel(packageName, level);
log.info("package logLevel changed==>key:{},package:{},oldLevel:{},newLevel:{},changeType:{}",
key, packageName, oldLevel,newLevel,change.getChangeType());
}
}
log.info("apollo config changed,LoggerConfig 更新完畢");
}
}
6、我們在 controller 的接口里增加如下代碼,便于觀察日志級別是否改變
?????
log.debug("debug...");
log.info("info...");
log.error("error...");
log.warn("warn...");
7、首先啟動spring boot項目,我們訪問測試接口,查看日志。
正是我們在 application.yml 上設(shè)置的 debug 日志級別。
8、接下來我們在 Apollo 上修改日志級別為 warn,然后發(fā)布。
日志里已經(jīng)看到我們的應(yīng)用已經(jīng)監(jiān)聽到配置的變化,并更新了日志級別
9、訪問一下測試接口,可看到已經(jīng)生效了。
?
這就實現(xiàn)了日志級別的熱修改。
如我們可以完全依賴 Apollo 上的日志級別,就可以直接把 application.yml 的日志級別去掉了。
但是,我們需要修改一下我們的 LoggerConfig 類了,因為目前這個類的修改日志級別的功能是在監(jiān)聽到 Apollo 的配置變化了之后修改的,當(dāng)我們的應(yīng)用剛部署時是沒有修改配置的,所以就沒有觸發(fā)執(zhí)行這個設(shè)置日志級別的方法。
我們只需要增加一個init方法即可,并在其上添加@PostConstruct 注解即可,這個注解就是初始化時就調(diào)用該方法,和 init method 作用一樣,這樣在我們的系統(tǒng)啟動時就可以從 Apollo 上拿到配置參數(shù)從而設(shè)置日志級別。
@PostConstruct //加載這個類時就執(zhí)行
private void init(){
log.info("初始化日志級別...");
Set<String> keyNames = config.getPropertyNames();
for (String key : keyNames) {
if (StringUtils.containsIgnoreCase(key, LOGGER_TAG)) {
String strLevel = config.getProperty(key, "info");
LogLevel level = LogLevel.valueOf(strLevel.toUpperCase());
String packageName = key.replace(LOGGER_TAG, "");
loggingSystem.setLogLevel(packageName, level);
log.info("init package logLevel==>key:{},package:{},level:{}", key, packageName, strLevel);
}
}
log.info("初始化日志級別完畢");
}
啟動
測試一下是不是warn級別
訪問測試接口,可以看到正是 warn級別。
?
再去修改為info,客戶端應(yīng)用監(jiān)聽到修改并重新設(shè)置了日志級別
訪問測試接口,已修改為info級別。
Apollo還支持,灰度發(fā)布、分環(huán)境、分集群配置,篇幅的原因關(guān)于Apollo應(yīng)用的介紹今天就先到這里啦。
覺得有幫助的話請點贊吧?~
熱文:
Redis的各種數(shù)據(jù)類型到底能玩出什么花兒?
聯(lián)合索引在B+樹上的存儲結(jié)構(gòu)及數(shù)據(jù)查找方式
嘮叨~
歡迎關(guān)注公眾號,編程大道,之前整理的 redis 和 MQ 的知識點思維導(dǎo)圖分享給大家
??