#頭條創作挑戰賽#
終身學習、樂于分享、共同成長!
前言
什麼是配置?
應用程式在啟動和運作的時候往往需要讀取一些配置資訊,配置基本上伴随着應用程式的整個生命周期,比如:資料庫連接配接參數、啟動參數等這些就是配置。
配置主要有以下幾個特點:
- 配置是獨立于程式的隻讀變量
配置對于程式是隻讀的,程式通過讀取配置來改變自己的行為,但是程式不應該去改變配置。
- 配置伴随應用的整個生命周期
配置貫穿于應用的整個生命周期,應用在啟動時通過讀取配置來初始化,在運作時根據配置調整行為。
比如:啟動時需要讀取服務的端口号、系統在運作過程中需要讀取定時政策執行定時任務等。
- 配置可以有多種加載方式
常見的有程式内部hardcode,配置檔案,環境變量,啟動參數,基于資料庫等。
- 配置需要治理
同一份程式在不同的環境(開發,測試,生産)、不同的叢集(如不同的資料中心)經常需要有不同的配置,是以需要有完善的環境、叢集配置管理。
應用中的配置如何治理?
在沒有配置中心之前,我們是直接把配置寫在應用中的application.properties或者application.yml或者其他類型檔案中的。
這樣做會有兩個問題:
- 當配置發生改變時需要重新打包釋出。
- 配置寫在工程裡面,通路權限難以控制,容易洩露生産配置資訊。
什麼是配置中心?
在微服務架構中,通常服務都會比較多,每個服務都有各自的配置,如果所有服務的配置都寫在應用裡,那管理難度将會非常大。配置中心的概念應運而生,配置中心将配置從各應用中剝離出來,對配置進行統一管理,應用自身不需要自己去管理配置。
一個合格的配置中心需要滿足以下特性:
- 配置項容易讀取和修改。
- 分布式環境下應用配置的可管理性,即提供遠端管理配置的能力。
- 支援對配置的修改的檢視以把控風險。
- 可以檢視配置修改的曆史記錄。
- 不同部署環境下應用配置的隔離性。
#主流的配置中心産品
- Spring Cloud Config
2014年9月,Spring Cloud開源生态元件,可以和Spring Cloud體系無縫整合,但依賴Git或SVN 。
- Apollo
2016年5月,攜程開源的配置管理中心,具備規範的權限、流程治理等特性。
- Nacos
2018年6月,阿裡開源的配置中心,也可以做RPC的服務發現。
三者對比:
對比項目\配置中心 | Spring Cloud Config | Apollo | Nacos |
開源時間 | 2014.9 | 2016.5 | 2018.6 |
配置實時推送 | 支援(Spring Cloud Bus) | 支援(HTTP長輪訓1s内) | 支援(HTTP長輪訓1s内) |
版本管理 | 支援(Git) | 自動管理 | 自動管理 |
版本復原 | 支援(Git) | 支援 | 支援 |
灰階釋出 | 支援 | 支援 | 支援 |
權限管理 | 支援 | 支援 | 支援 |
多叢集/多環境 | 支援 | 支援 | 支援 |
監聽查詢 | 支援 | 支援 | 支援 |
多語言 | 僅支援Java | Go、Java、C++、Python、.net、OpenAPI | Java、Python、nodejs、OpenAPI |
配置格式檢驗 | 不支援 | 支援 | 支援 |
通訊協定 | HTTP和AMQP | HTTP | HTTP |
資料一緻性 | Git保障資料一緻性, Config-Server從Git讀取資料 | 資料庫模拟消息隊列, Apollo定時讀取消息 | HTTP異步通知 |
單機讀(tps) | 7(限流所緻) | 9000 | 15000 |
單機寫(tps) | 5(限流所緻) | 1100 | 1800 |
3節點讀 | 21(限流所緻) | 27000 | 45000 |
3節點寫 | 5(限流所緻) | 3300 | 5600 |
快速開始
Spring Cloud Config需要內建Git或者SVN來實作配置,複雜且比較低效,Apollo主要應用于Dubbo那套分布式微服務架構,是以這裡我們主要以Nacos配置中心進行學習。
Nacos包含的注冊中心+配置中心,以下隻說配置中心。關于Nacos如何安裝部署可以會看第2章的服務注冊與發現。
本文中的主要例子參照于Nacos-config (opens new window)官網。
準備配置
在nacos server中建立nacosconfig.properties。
Data ID: nacos-config.properties
Group : DEFAULT_GROUP
配置格式: Properties
配置内容: user.name=nacos-config-properties
user.age=90
注意:dataId是以 properties(預設的檔案擴充名方式)為擴充名。
Nacos官方推薦的配置管理的最佳工程實踐:
- Namespace:代表不同環境,如開發、測試、生産環境。
- Group:代表某項目,如XX醫療項目、XX電商項目
- DataId:每個項目下往往有若幹個工程(微服務),每個配置集(DataId)是一個工程(微服務)的主配置檔案
搭建用戶端服務
示例代碼工程位于step-05
工程結構:
springcloudalibaba-step-05
├─src
│ └─main
│ ├─resources
│ │ └─bootstrap.yml
│ └─java
│ └─cn
│ └─codelab
│ └─springcloudalibaba
│ └─study
│ └─step05
│ └─NacosConfigApplication.java
└─pom.xml
- 引入依賴
<!-- nacos-config依賴 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 添加bootstrap.yml
這裡解釋一下為什麼要使用bootstrap.yml檔案,因為官網中有說明必須使用 bootstrap.properties 配置檔案來配置Nacos Server 位址,是以這裡使用bootstrap.yml配置檔案,properties與yml隻是兩種檔案格式類型,SpringBoot都支援加載識别,隻要檔案名稱是bootstrap即可。
可能還有同學會有疑問,為什麼沒有了application.yml檔案,由于這兩個檔案SpringBoot都會讀取,是以我這裡直接把所有的配置都挪到一個bootstrap.yml配置檔案中了。
server:
port: 8005
spring:
application:
name: nacos-config # 應用名稱 (nacos會将該名稱當做服務名稱)
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
- 編寫測試代碼
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);
while(true) {
//當動态配置重新整理時,會更新到 Enviroment中,是以這裡每隔一秒中從Enviroment中擷取配置
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" + userName + "; age: " + userAge);
TimeUnit.SECONDS.sleep(1);
}
}
}
- 啟動服務測試
啟動NacosConfigApplication這個Demo可以看到控制台的輸出如下圖:
Nacos-config天生預設就支援配置的動态更新,比如我們把user.age屬性改為91,觀察控制台輸出:
具體實作原理是:Nacos控制台修改配置 ➜ Nacos配置中心重新生成配置的MD5值推送用戶端 ➜ 用戶端收到MD5值變更,重新拉取配置
Nacos-config個性化配置檔案的屬性
Nacos 資料模型 Key 由三元組唯一确定, Namespace預設是空串,公共命名空間(public),分組預設是DEFAULT_GROUP。
上面的例子帶着大家快速開始體驗了一下Nacos-config的使用,例子中采用約定大于配置的規則來使用的,但在實際項目中都會根據項目的實際情況有一些特殊化的定制配置,那麼接下來就介紹關于Nacos-config的個性化配置使用。
- 基于 dataId 為 yaml 的檔案擴充名配置方式
前面我們講到dataId是以 properties(預設的檔案擴充名方式)為擴充名,也就是說在我們沒有指定檔案擴充名的情況下,Nacos-config Client預設是讀取properties類型的配置檔案的,如果想修改怎麼做呢?
spring-cloud-starter-alibaba-nacos-config 對于yaml格式也是完美支援的。
這個時候隻需要完成以下兩步:
1、在應用的 bootstrap.yml 配置檔案中顯示的聲明 dataId 檔案擴充名。如下所示
spring:
cloud:
nacos:
config:
file-extension=yaml
2、在 Nacos 的控制台新增一個dataId為yaml為擴充名的配置,如下所示:
Data ID: nacos-config.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置内容: user.name: nacos-config-yaml
user.age: 68
重新開機服務可以看到輸出:
- 支援自定義 namespace 的配置
用于進行租戶粒度的配置隔離。不同的命名空間下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用場景之一是不同環境的配置的區分隔離,例如開發測試環境和生産環境的資源(如配置、服務)隔離等。
建立一個命名空間
在沒有明确指定 ${spring.cloud.nacos.config.namespace} 配置的情況下, 預設使用的是 Nacos 上 Public 這個namespace。如果需要使用自定義的命名空間,可以通過以下配置來實作:
spring:
cloud:
nacos:
config:
namespace: d8f2135d-4ed8-42e4-8842-cdea14152b02 # 指定命名空間
命名空間ID可以從Nacos控制台中擷取:
**注意:**該配置必須放在 bootstrap.yml 檔案中。此外 spring.cloud.nacos.config.namespace 的值是 namespace 對應的 id,id 值可以在 Nacos 的控制台擷取。并且在添加配置時注意不要選擇其他的 namespace,否則将會導緻讀取不到正确的配置。
- 支援自定義 Group 的配置
Group是組織配置的次元之一。通過一個有意義的字元串(如 Buy 或 Trade )對配置集進行分組,進而區分Data ID相同的配置集。當你在Nacos上建立一個配置時,如果未填寫配置分組的名稱,則配置分組的名稱預設采用DEFAULT_GROUP 。
配置分組的常見場景:不同的應用或元件使用了相同的配置類型,如database_url配置和MQ_topic配置。
在沒有明确指定 ${spring.cloud.nacos.config.group} 配置的情況下, 預設使用的是DEFAULT_GROUP。如果需要自定義自己的Group,可以通過以下配置來實作:
spring:
cloud:
nacos:
config:
group: DEVELOP_GROUP
- 支援自定義擴充的 Data Id 配置
Data ID是組織劃配置設定置的次元之一。Data ID通常用于組織劃分系統的配置集。一個系統或者應用可以包含多個配置集,每個配置集都可以被一個有意義的名稱辨別。
Data ID通常采用類Java 包(如 com.taobao.tc.refund.log.level)的命名規則保證全局唯一性。此命名規則非強制。
通過自定義擴充的Data Id配置,既可以解決多個應用間配置共享的問題,又可以支援一個應用有多個配置檔案。
spring.application.name=opensource-service-provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# config external configuration
# 1、Data Id 在預設的組 DEFAULT_GROUP,不支援配置的動态重新整理
spring.cloud.nacos.config.extension-configs[0].data-id=ext-config-common01.properties
# 2、Data Id 不在預設的組,不支援動态重新整理
spring.cloud.nacos.config.extension-configs[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.extension-configs[1].group=GLOBALE_GROUP
# 3、Data Id 既不在預設的組,也支援動态重新整理
spring.cloud.nacos.config.extension-configs[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.extension-configs[2].group=REFRESH_GROUP
spring.cloud.nacos.config.extension-configs[2].refresh=true
Spring Cloud Alibaba Nacos Config 目前提供了三種配置能力從 Nacos 拉取相關的配置。
- 通過 spring.cloud.nacos.config.shared-configs 支援多個共享 Data Id 的配置
- 通過 spring.cloud.nacos.config.ext-config[n].data-id 的方式支援多個擴充 Data Id 的配置
- 通過内部相關規則(應用名、應用名+ Profile )自動生成相關的 Data Id 配置
當三種方式共同使用時,他們的一個優先級關系是:A < B < C
優先級從高到低:
- nacos-config-product.yaml 精準配置
- nacos-config.yaml 同工程不同環境的通用配置
- ext-config: 不同工程 擴充配置
- shared-dataids 不同工程通用配置
@RefreshScope注解的使用
Spring提供的@Value注解可以擷取到配置中心的值,但是無法動态感覺修改後的值,需要利用@RefreshScope注解。
/**
* @author Seven
* @description
* @Gitee https://gitee.com/it-codelab
* @Copyright 公衆号:Seven的代碼實驗室
*/
@RestController
@RefreshScope // 配合@Value注解實作自動重新整理配置
public class TestController {
@Value("${user.age}")
private Integer age;
@RequestMapping("/test")
public Integer test() {
return age;
}
}
灰階釋出
Nacos服務端修改配置後,勾選Beat釋出,指定IP位址,然後選擇釋出Beta。
點選釋出之後,隻有指定的IP節點的配置被更新。
總結
- 本章介紹什麼是配置以及配置中心的原理,微服務架構下為什麼需要配置中心。
- 常見的配置中心産品有Spring Cloud Config、Apollo、Nacos,Spring Cloud Config需要內建Git或者SVN來實作配置,複雜且比較低效,Apollo主要應用于Dubbo分布式微服務架構,在SpringCloudAlibaba微服務架構體系下主流使用Nacos作為配置中心。
- 快速使用Nacos配置中心以及詳解常用的各項配置。
完整代碼示例可在公衆号【Seven的代碼實驗室】中回複SpringCloudAlibaba擷取。