1. 程式人生 > >白話SpringCloud | 第七章:分散式配置中心的使用

白話SpringCloud | 第七章:分散式配置中心的使用

前言

介紹完服務的容錯保護處理,接下來我們來了解下關於分散式配置中心的相關知識和使用。眾所周知,隨著專案的越來越多,日益龐大,每個子專案都會伴隨著不同的配置項,於此也就多了很多的配置檔案。倘若某些配置資訊修改,可能就會伴隨著一系列配置檔案的更新和相應服務的重啟操作了。這對於實施而言,也是噩夢一般的存在,增加了一系列運維成本,也會無形中提高出錯的機率。所以在微服務越來越多時,就會引入今天要講解的分散式配置中心,它就是來解決此類問題的。話不多說,開始吧~

一點知識

為什麼要統一管理微服務配置

在寫這篇文章之前,在公眾號裡有推送了一篇《為什麼需要分散式配置中心》的文章。裡面也大致說明了,大家可以看一看。簡單來說,就是隨著業務的發展、微服務架構的升級,服務的數量、程式的配置日益增多(各種微服務、各種伺服器地址、各種引數),傳統的配置檔案方式和資料庫的方式已無法滿足開發人員對配置管理的要求,即

  • 安全性:配置跟隨原始碼儲存在程式碼庫中,容易造成配置洩漏;

  • 時效性:修改配置,需要重啟服務才能生效;

  • 侷限性:無法支援動態調整:例如日誌開關、功能開關;

其實說白了,就是當業務需求有變更時,可以通過修改配置檔案或者引數的形式,能夠自動更新配置。減少不必要的重啟服務的操作。正常情況下,一般的業務系統都有個引數配置表的,裡面記錄著不同業務引數,以此來應對不同的需求場景,也就是需求口中常說的:要能靈活配置。

而在微服務中,由於每個微服務都是獨立的資料庫,傳統的配置無法滿足了。所以才出現了分散式配置中心服務,專門來解決此類問題的。

在微服務架構中,微服務的統一配置管理一般有以下需求:

  • 集中管理配置:一個使用微服務架構的應用系統可能會包括成千上萬個微服務,因此集中管理配置是非常有必要的。
  • 不同環境不同配置:資料來源配置在不同的環境(開發、測試、預釋出、生產等)中是不同的。
  • 執行期間可動態調整:可根據各個微服務的負載情況,動態調整資料來源連線池大小或熔斷閾值,並且在調整配置時不重啟微服務。
  • 配置修改後自動更新:如配置內容發生變化,微服務能夠自動更新配置。

綜上所述,對於微服務架構而言,一個通用的配置管理機制必不可少,常見做法是使用配置伺服器管理配置。目前市面上開源的配置中心有很多,如

  • Apollo(阿波羅):攜程框架部門研發的分散式配置中心,能夠集中化管理應用不同環境、不同叢集的配置,配置修改後能夠實時推送到應用端,並且具備規範的許可權、流程治理等特性,適用於微服務配置管理場景。
  • Qconf:一個分散式配置管理工具,360出品。
  • Disconf:專注於各種「分散式系統配置管理」的「通用元件」和「通用平臺」, 提供統一的「配置管理服務」。

具體的可以看看之前說的文章《為什麼需要分散式配置中心》,這裡就不過多闡述了。

Spring-Cloud-config實踐

何為SpringCloudConfig

Spring Cloud Config為分散式系統外部化配置提供了服務端和客戶端的支援,它包括Config ServerConfig Client兩部分。目前支援gitsvnvaultjdbc本地幾種儲存方式。

最常用的儲存方式就是git了。

簡單來說,各客戶端程式通過訪問服務端獲取相應的配置資訊。接下來我們看看下面這張圖

  • 遠端Git倉庫:儲存配置檔案。
  • ConfigServer:分散式配置管理中心,會於維護自己的git倉庫資訊。
  • 本地Git倉庫:在ConfigServer中,每次客戶端請求獲取配置資訊時,都會從git倉庫獲取最新的配置到本地,然後本地讀取並返回,遠端無法獲取時,使用本地倉庫資訊。

從上圖可以看出,Config Server巧妙地通過git clone將配置資訊存於本地,起到了快取的作用,即使當Git服務端無法訪問的時候,依然可以取Config Server中的快取內容進行使用。

這裡以git為例,做個簡單示例。 首先,在github中建立一個目錄:spring-cloud-config-repo,來存放配置檔案資訊。

my-config-client-dev.properties

config=this is dev!

my-config-client-dev.properties

config=this is test!

注意:因為存在多個專案都是用配置中心問題,而每個專案的應用名稱是不盡相同的,所以配置檔案的命名方式即為: 應用名+環境變數(profile)的命名方式。因此,每個應用理應設定應用名稱,是個好習慣。具體的對映規則,在Server端會進行說明的。

Server端

建立工程:spring-cloud-confg-server 0.引入pom依賴。

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

1.啟動類加入@EnableConfigServer註解,宣告是ConfigServer

@SpringBootApplication
@EnableConfigServer
@Slf4j
public class SpringCloudConfigServerApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringCloudConfigServerApplication.class, args);
        log.info("spring-cloud-config-server啟動!");
    }
}

2.配置檔案,新增git倉庫相關資訊。

spring.application.name=spring-cloud-config-server
server.port=5678

#配置檔案git配置
spring.cloud.config.server.git.uri=https://github.com/xie19900123/spring-cloud-learning.git
# 搜尋路徑,即配置檔案的目錄,可配置多個,逗號分隔。預設為根目錄。
spring.cloud.config.server.git.searchPaths=spring-cloud-config-repo
# git使用者名稱和密碼 針對私有倉庫而言需要填寫
spring.cloud.config.server.git.username=
spring.cloud.config.server.git.password=

3.啟動應用,訪問http://127.0.0.1:5678/my-config-client-dev.properties ,返回了配置檔案的資訊,說明已經讀取到遠端倉庫資訊了。

my-config-client-dev

我們可以通過訪問配置資訊的URL與配置檔案的對映關係,獲取相應的配置資訊。

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

url會對映{application}-{profile}.properties對應的配置檔案, 其中{label}對應Git上不同的分支,預設為master。我們可以嘗試構造不同的url來訪問不同的配置內容, 比如: 要訪問master分支,my-config-client應用的dev環境

http://127.0.0.1:5678/my-config-client/dev/master

返回的資訊:

{
    "name": "my-config-client",
    "profiles": ["dev"],
    "label": "master",
    "version": "51d81a5aacce45b97af6db2482769fe02873c548",
    "state": null,
    "propertySources": [{
        "name": "https://github.com/xie19900123/spring-cloud-learning.git/spring-cloud-config-repo/my-config-client-dev.properties",
        "source": {
            "config": "this is dev!"
        }
    }]
}

此時,檢視控制檯,可以獲悉本地也儲存著一份配置資訊。

2018-10-09 23:32:46.833  INFO 988 --- [nio-5678-exec-2] o.s.c.c.s.e.NativeEnvironmentRepository  : Adding property source: file:/C:/Users/xiede/AppData/Local/Temp/config-repo-7233984840222622045/spring-cloud-config-repo/my-config-client-dev.properties
2018-10-09 23:32:46.834  INFO 988 --- [nio-5678-exec-2] s.c.a.AnnotationConfigApplicationContext : Closing org.spring[email protected]66e76432: startup date [Tue Oct 09 23:32:46 CST 2018]; root of context hierarchy

檢視本地倉庫目錄: 本地倉庫

此時,修改遠端的配置檔案,再次訪問可以看見返回的引數是最新修改後的引數值了,大家可以自行試試。

Client端

建立一個客戶端:spring-cloud-confg-client。當然也可以改造原來的應用了,只需加入相應pom檔案和配置檔案即可。 0.加入pom依賴。

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

1.建立啟動類,就是一個正常的web應用。

/**
 * Spring Cloud Config client 示例
 * @author oKong
 *
 */
@SpringBootApplication
@Slf4j
public class SpringCloudConfigClientApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringCloudConfigClientApplication.class, args);
        log.info("spring-cloud-config-client啟動!");
    }

}

2.配置檔案新增:bootstrap.properties和常規的application.properties

bootstrap.properties

# 設定分支
spring.cloud.config.label=master
# 環境變數
spring.cloud.config.profile=dev
# 是否使用註冊中心方式進行獲取 後續會進行講解
#spring.cloud.config.discovery.enabled=false
# 服務端地址 
# 在不使用註冊中心模式下 直接填寫實際地址
spring.cloud.config.uri=http://127.0.0.1:5678
# 註冊中心應用id 下一章節會進行講解
#spring.cloud.config.discovery.service-id=

application.properties

# 設定應用名稱,需要和配置檔案匹配
spring.application.name=my-config-client
server.port=5666

這裡需要注意:

spring-cloud-config相關的屬性必須配置在bootstrap.properties,config部分內容才能被正確載入。因為config的相關配置會先於application.properties,而bootstrap.properties的載入也是先於application.properties

3.編寫一個控制層,利用@Value進行引數測試。

/**
 * config client 簡單示例
 * @author oKong
 *
 */
@RestController
public class DemoController {

    @Value("${config}")
    String config;
    
    @GetMapping("/")
    public String demo() {
        return "返回的config引數值為:" + config;
    }
}

4.啟動應用,訪問:http://127.0.0.1:5666/ ,可以看見配置資訊已經被正確返回了。

自此,一個簡單的配置中心示例就結束了。 目前為止,我們還沒有手動去修改遠端的配置檔案引數值,可以試試,在修改後,客戶端去返回相應的引數值,會發現還是舊的,並沒有進行更新操作。因為配置檔案是是在應用啟動的時候進行載入的,而且遠端倉庫修改了配置檔案,客戶端並不知道已經修改了,不會發起請求的。關於配置引數自動更新相關知識點,會在下一章節進行講解的。

參考資料

總結

本章節主要講解了常規操作下,如何使用SpringCloudConfig進行統一引數配置管理。針對配置動態重新整理,實時生效相關知識點,會在下一章節進行單獨講解的,本章節先讓大家有個直觀的認識,瞭解下SpringCloudConfig實現的一些機制。本文僅僅是講解了git示例,有興趣的同學可以試試其他的,比如svn或者本地資源庫等形式。都是類似配置,就不加以說明了。

最後

目前網際網路上大佬都有分享SpringCloud系列教程,內容可能會類似,望多多包涵了。原創不易,碼字不易,還希望大家多多支援。若文中有錯誤之處,還望提出,謝謝。

老生常談

  • 個人QQ:499452441
  • 微信公眾號:lqdevOps

公眾號