[TOC]java
爲何要須要配置管理?git
在微服務架構中,每一個微服務都有可能會存在多個實例,爲了保證同一微服務不一樣實例的配置文件內容一致,咱們就須要有一個服務能夠對微服務項目的配置文件進行統一管理,一般咱們將其稱之爲統一配置管理中心。由於若是配置文件的內容不一致,有可能會致使同一微服務的不一樣實例在行爲上發生差別,從而致使一些錯誤。github
除此以外,在企業開發中還要求項目在不一樣環境使用不一樣配置,以及能夠在不重啓服務的狀況下實現配置文件的動態刷新,爲了實現這些需求咱們也得使用到統一配置管理中心spring
目前業界比較流行的統一配置管理中心組件有Spring Cloud的Config、Spring Cloud Alibaba的Nacos以及攜程開源的Apollo。本文主要介紹Nacos做爲統一配置管理中心的使用,關於其餘配置中心組件以及Nacos的基本使用能夠參考以下文章:數據庫
接下來,咱們看看如何使用Nacos管理配置文件,如今我有一段接口代碼以下:json
@RestController @RequiredArgsConstructor public class TestController { @Value("${your.configuration}") private String yourConfiguration; @GetMapping("/getConfiguration") public String getConfiguration(){ return yourConfiguration; } }
這段代碼讀取了一個配置項,此時該配置項存在於項目的application.yml
文件中,以下:bootstrap
your: configuration: your_value
那麼咱們要如何使用Nacos管理這段配置呢?首先須要爲項目整合Nacos配置管理的功能,在pom.xml文件中添加以下依賴:windows
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
Greenwich.SR1
,Alibaba的版本爲2.1.0.RELEASE
而後在resources
目錄下新建一個名爲bootstrap.yml
的文件,添加以下配置項:bash
spring: cloud: nacos: config: # 指定做爲配置中心的nacos server地址 server-addr: 127.0.0.1:8848 # 配置文件格式 file-extension: yaml discovery: # 指定做爲服務註冊中心的nacos server地址 server-addr: 127.0.0.1:8848 application: name: content-center profiles: active: dev
到Nacos的管理頁面的「配置列表」中新建配置:
服務器
新建的配置內容以下圖:
注意,這裏的Data ID是具備必定格式的,須要與項目中的配置對應上。如上圖中的:content-center-dev.yaml,其中content-center是微服務名稱,dev是環境,yaml是配置文件的格式。這裏簡單整理成了一張對照圖,以下:
.yaml
,也能夠是.yml
,由於這兩種後綴其實都是表示同一種文件格式到目前爲止,咱們就已經爲項目整合了Nacos的配置管理功能,並在Nacos Server上新建了項目所需的配置。此時就能夠將以前配置在application.yml
文件中的配置項給刪除掉。而後啓動項目,訪問/getConfiguration
接口,返回結果以下則表明整合成功:
在實際的企業開發中,咱們一般但願在配置中心上修改了配置項後,不須要重啓項目就可以實現實時的動態配置刷新。對於整合了Nacos的微服務項目來講,想要實現這個功能是很簡單的,只須要在讀取了配置屬性的類上加上@RefreshScope
註解便可。以下示例:
// 該註解用於標識哪些地方須要動態刷新配置,能夠寫在類及方法上 @RefreshScope @RestController @RequiredArgsConstructor public class TestController { @Value("${your.configuration}") private String yourConfiguration; @GetMapping("/getConfiguration") public String getConfiguration(){ return yourConfiguration; } }
添加完該註解後,重啓項目,而後到Nacos上修改以前配置項的值,點擊發布後會有一個內容比較的提示,能夠看到我將以前的your_value
改爲了my_value
:
點擊確認發佈後,而後再訪問/getConfiguration
接口,返回的就是修改後的值了,而此時咱們並無重啓項目:
除了以上所介紹的動態刷新以外,還有一個比較重要的功能:配置回滾。若是有一天修改某些配置項併發布後發現手滑改錯了,致使項目運行出問題,那麼就可使用回滾功能能夠幫助我快速回滾到某個特定的版本上。咱們能夠在Nacos的「歷史版本」頁面中查詢指定配置的歷史版本,以下圖:
點擊「詳情」能夠查看到具體的配置內容:
點擊「回滾配置」則能夠回滾到指定的歷史版本,例如我這裏就回滾到初始版本:
提示回滾成功後訪問/getConfiguration
接口,會發現報錯了:
這是目前Nacos 1.1版本的一個Bug,當選擇回滾的版本是最第一版本時就會發生這個問題。官方稱會在1.2版本中修復該問題,而我目前使用的是最新的1.1.3版本,仍屬於1.1版本(2019-09-10),因此該bug還存在。相關的issues以下:
在1.1版本下,只要回滾的不是初始版本則不會觸發這個bug,回滾其餘版本是能夠正常使用的,因此該問題注意一下便可規避
注:觸發該bug後,配置內容因爲回滾失敗會丟失,此時須要從新建立配置
以上咱們介紹了Nacos做爲配置中心的基本使用,而本小節將介紹相同應用下的配置共享,所謂的配置共享就是一些配置項能夠在相同應用的不一樣環境中進行共享。
例如以上示例中的${your.configuration}
配置項,咱們但願在全部的環境下該配置項都是相同的值,而又不想在每一個環境的配置文件裏面都配置一遍,也就是說這個配置項是全部環境通用的,那麼這時候就須要將該配置項在全部環境中共享了。
想要實現配置共享只須要新建一個配置文件便可,首先咱們來看一段日誌信息,當咱們啓動項目時,控制檯會出輸出以下一段日誌信息:
2019-09-11 20:47:42.197 INFO 13778 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='content-center-dev.yaml'}, NacosPropertySource {name='content-center.yaml'}]}
從該日誌信息能夠看到,項目在啓動時會到Nacos上讀取兩個配置文件,即content-center-dev.yaml
和content-center.yaml
,其中content-center-dev.yaml
裏保存的是開發環境下特定的配置,而content-center.yaml
裏保存的則是全部環境下通用的配置。項目在啓動時具體讀取哪一個環境的配置文件是由bootstrap.yml
文件中的spring.profiles.active
配置項所決定的。
既然咱們知道保存在content-center.yaml
裏的配置項會在全部環境中共享,那麼只須要到Nacos上新建這個配置文件便可。以下示例:
新建完成後,修改項目中的spring.profiles.active
爲其餘環境,而後重啓項目,此時訪問/getConfiguration
接口,能夠看到返回的是通用配置文件裏所配置的值:
${your.configuration}
配置項同時存在於content-center-dev.yaml
和content-center.yaml
中,若spring.profiles.active
的值爲dev
,那麼讀取的將是content-center-dev.yaml
裏所配置的值。以上介紹了相同應用在不一樣環境下的配置共享,但如何實現不一樣應用之間的配置共享呢?例如咱們常常會遇到微服務A和微服務B的數據庫配置是同樣的,若是能將這段相同的配置在這兩個服務之間共享,那麼就能夠省去一些重複的工做。
目前Nacos提供了兩種方式能夠實現不一樣應用之間的配置共享,第一種方式是使用shared-dataids
。接下來咱們進行一個簡單的演示,首先須要到Nacos上建立一些共享配置,以下示例:
其中common1.yaml
配置內容以下:
common1: configuration1: common1_value
common2.yaml
配置內容以下:
common2: configuration2: common2_value
建立共享配置完成後,修改項目中的bootstrap.yml
文件以下:
spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 config: # 指定共享配置的DataId,多個使用,分隔 # 越靠後,優先級越高;common2.yml > common1.yaml # .yaml後綴不能少,目前只支持yaml/properties shared-dataids: common1.yaml,common2.yaml # 指定哪些共享配置支持動態刷新,多個使用,分隔 refreshable-dataids: common1.yaml server-addr: 127.0.0.1:8848 file-extension: yaml application: name: content-center profiles: active: dev
從以上的配置示例能夠看出,其實shared-dataids
的主要做用就是用來指定共享配置的Data ID,使得該微服務能夠讀取這些共享配置。同理,其餘微服務若想讀取這些共享配置,只需在項目的bootstrap.yml
文件中添加相應的shared-dataids
配置便可,如此一來就實現了多個微服務之間的配置共享。
而後咱們來寫兩個簡單的接口驗證一下是否能正常讀取這兩個共享配置的值,代碼以下:
@RefreshScope @RestController @RequiredArgsConstructor public class TestController { @Value("${common1.configuration1}") private String common1Configuration; @Value("${common2.configuration2}") private String common2Configuration; @GetMapping("/getCommonConfiguration1") public String getCommonConfiguration1() { return common1Configuration; } @GetMapping("/getCommonConfiguration2") public String getCommonConfiguration2() { return common2Configuration; } }
啓動項目,訪問結果以下:
第二種方式也是差很少的,只不過使用的配置項是ext-config
,修改項目中的bootstrap.yml
文件以下:
spring: cloud: nacos: config: server-addr: 127.0.0.1:8848 file-extension: yaml ext-config: # 需共享的DataId,yaml後綴不能少,目前只支持yaml/properties # 越靠後,優先級越高 優先級common2.yaml > common1.yaml - data-id: common1.yaml # common1.yaml所在的group group: DEFAULT_GROUP # 是否容許刷新,默認false refresh: true - data-id: common2.yaml group: DEFAULT_GROUP refresh: true application: name: content-center profiles: active: dev
ext-config
提供了較爲細化的配置方式,而且能夠指定配置組。到目前爲止,咱們介紹了三種從Nacos上讀取配置的方式,其優先級以下:
shared-dataids < ext-config < 自動
除此以外,當存在相同的遠程配置和本地配置時,遠程配置優先級要高於本地配置文件。但能夠經過添加以下配置調整,須要注意的是這段配置須要放在遠程配置纔會生效:
spring: cloud: config: # 是否容許本地配置覆蓋遠程配置,默認true allow-override: true # 是否一切以本地配置爲準,默認false override-none: false # 系統環境變量或系統屬性才能覆蓋遠程配置文件的配置 # 本地配置文件中配置的優先級低於遠程配置,默認true override-system-properties: true
在介紹爲項目整合Nacos作配置管理服務的時候,示例裏將Nacos Config的相關配置都寫在一個bootstrap.yml
文件裏,可是爲何要使用bootstrap.yml
呢?使用application.yml
不能夠嗎?
這是實際上是由於bootstrap.yml
會被優先讀取,也就是說若是項目裏同時存在一個bootstrap.yml
和一個application.yml
的話,那麼bootstrap.yml
將會優先於application.yml
被Spring Boot讀取。這樣才能實現鏈接外部的配置管理服務器,從遠程讀取一些必要的配置,避免項目在啓動時缺失必要配置項而致使啓動失敗。
這裏實際涉及到一個引導上下文的概念,它是ApplicationContext
的父上下文,而且是由Spring Cloud提供的, 它所在的位置以下圖所示:
引導上下文在prepareEnvironment
的階段就會被建立,建立時會讀取bootstrap.yml
的內容做爲引導配置, 所以bootstrap.yml
優先於application.yml
加載。引導上下文與操做系統的引導程序很是相似,而bootstrap.yml
就至關於設置引導程序的相關指令。
Nacos會將數據持久化到本地,當Nacos做爲服務發現組件時,默認會將服務的註冊信息存儲在以下目錄中:
類Unix系統:~/nacos/naming windows系統:C:\用戶\{用戶名}\nacos\naming
具體文件以下圖所示:
打開其中一個文件,能夠看到服務註冊信息的格式以下:
{ "metadata": {}, "dom": "DEFAULT_GROUP@@content-center", "cacheMillis": 10000, "useSpecifiedURL": false, "hosts": [], "name": "DEFAULT_GROUP@@content-center", "checksum": "f797b857f5312a616a875924ecf6481a", "lastRefTime": 1564815242804, "env": "", "clusters": "" }
當Nacos做爲配置中心時,配置數據會分爲兩份並存儲在兩個地方,其中一份存儲在內嵌的derby數據庫中,這是Apache開源的一個徹底由Java編寫的內嵌數據庫,而derby會有一個數據目錄,以下:
$NACOS_HOME/data/derby-data
咱們可使用IDEA鏈接derby來查看相關的數據表及存儲內容,在右邊菜單欄中點開Database -> 點擊+符號添加數據庫鏈接 -> Data Source -> Apache Derby。以下圖所示:
注意,此時須要將Nacos Server給中止掉,不然是沒法鏈接的。中止Nacos Server以後,填寫相關的鏈接信息,Path填的是derby的數據目錄,用戶和密碼默認都是nacos。以下圖所示:
鏈接成功後,能夠看到derby中的數據表以下:
其中CONFIG_INFO
表存儲了配置數據,打開該表能夠看到內容以下:
須要注意的是derby並不能用於生產環境,由於它是一個內嵌數據庫,沒法實現高可用和集羣部署,因此通常搭建生產可用的Nacos時會將數據庫改成使用MySQL等非內嵌數據庫。
而另外一份數據存儲在以下目錄,主要是一些快照等數據:
類Unix系統:~/nacos/config windows系統:C:\用戶\{用戶名}\nacos\config
快照主要用於提高性能以及作容災備份,具體文件以下圖所示: