白話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.springframework.context.annotation.AnnotationConfigApplicationContext@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/ ,可以看見配置信息已經被正確返回了。


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


參考資料

  1. https://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#_spring_cloud_config

  2. 為什么需要分布式配置中心?

總結

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

最后

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

老生常談

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

公眾號

個人博客:http://blog.lqdev.cn

源碼示例:https://github.com/xie19900123/spring-cloud-learning


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM