Spring Cloud 學習筆記 - No.3 分布式配置 Config

請先閱讀之前的內容:

Spring Cloud Config 介紹

https://cloud.spring.io/spring-cloud-config/

Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system.

Spring Cloud Config 是 Spring Cloud 團隊創建的一個全新項目,用來為分布式系統中的基礎設施和微服務應用提供集中化的和可擴展的外部配置支持。

它分為服務端與客戶端兩個部分:

  • 服務端也稱為分布式配置中心,它是一個獨立的微服務應用,用來連接配置倉庫(例如 Git)并為客戶端提供獲取配置信息、加密/解密信息等訪問接口
  • 客戶端則是微服務架構中的各個微服務應用或基礎設施,它們通過指定的配置中心來管理應用資源與業務相關的配置內容,并在啟動的時候從配置中心獲取和加載配置信息。

Spring Cloud Config 實現了對服務端和客戶端中環境變量 Environment 和屬性配置 PropertySource 的抽象映射,所以它除了適用于Spring 構建的應用程序之外,也可以在任何其他語言運行的應用程序中使用。
由于 Spring Cloud Config 實現的配置中心默認采用 Git 來存儲配置信息,所以使用 Spring Cloud Config構建的配置服務器,天然就支持對微服務應用配置信息的版本管理,并且可以通過 Git 客戶端工具來方便的管理和訪問配置內容。當然它也提供了對其他存儲方式的支持,比如:SVN倉庫、本地化文件系統。

一個分布式配置的場景

場景描述:我們有一個服務,部署在分布式的環境上,服務需要訪問數據庫。通常情況下,我們將數據庫的配置(例如數據庫地址,用戶名,密碼等等)以文件的形式放置在項目自身的目錄中。
這樣的問題是,假如配置發生了變化(例如數據庫用戶名改變了),我們需要修改配置文件,重新 Build,重新 Deploy。
現在我們嘗試將配置文件放在第三方的位置,例如 Git。然后我們創建一個配置中心 config-server,它負責去 Git 倉庫里讀取文件內容。最后其他應用程序,例如之前創建的 eureka-consumer 通過配置中心 config-server 去讀取配置。
在這里有一個問題,我們只創建了一個配置中心 config-server,這樣的話,會出現單點失敗,并且負載均衡得不到保障。
因此我們需要創建多個配置中心,即分布式配置中心,每一個 config-server 都會以服務的形式注冊到之前創建的服務注冊中心 eureka-server 中去。
結構如下:該圖引用自 https://blog.csdn.net/fox9916/article/details/79499854/

分布式配置中心

首先我們在 Github 上創建一個 repo,位置:https://github.com/chenxiangcyr/spring-cloud-config-repo-demo??梢钥吹?,包括三個不同環境的配置文件(開發,測試,生產):

三個不同環境的配置文件

其中一個文件的內容如下 demo-dev.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306
jdbc.username=rootDev
jdbc.password=rootDev

config-server 配置中心

通過的 Spring Assistant 插件來創建項目,具體過程不再贅述。
pom.xml 中導入了如下的依賴:

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

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

隨后在啟動程序中通過 @EnableConfigServer 來開啟 Spring Cloud Config 的服務端功能。:

@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

隨后在 application.properties 中添加配置服務的基本信息以及 Git 倉庫的相關信息。

spring.application.name=config-server
server.port=4001

# 服務注冊中心
eureka.client.serviceUrl.defaultZone=http://localhost:1234/eureka/

# Git倉庫地址
spring.cloud.config.server.git.uri=https://github.com/chenxiangcyr/spring-cloud-config-repo-demo/

# 如果我們的Git倉庫需要權限訪問,那么可以通過配置下面的兩個屬性來實現
# spring.cloud.config.server.git.username=
# spring.cloud.config.server.git.password=

# 配置文件所在的目錄
spring.cloud.config.server.git.search-paths=/**

# 配置文件所在的分支
spring.cloud.config.label=master

management.endpoints.web.exposure.include=*

最后我們分別以 4001 和 4002 兩個端口來啟動 config-server 配置中心,可以看到每一個 config-server 都會以服務的形式注冊到之前創建的服務注冊中心 eureka-server 中去,點擊 http://127.0.0.1:1234/ 查看如下:

每一個 config-server 都會以服務的形式注冊到之前創建的服務注冊中心 eureka-server 中去

隨后我們就可以通過瀏覽器等工具直接來訪問到我們的配置內容了。訪問配置信息的 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。
例如我們通過 http://127.0.0.1:4001/demo/dev/ 的形式讀取配置文件的具體內容:

{
    name: "demo", 
    profiles: [
        "dev"
    ], 
    label: null, 
    version: "92f9ab1bff77011b8ab16f0d2dc7e3f24e326f6d", 
    state: null, 
    propertySources: [
        {
            name: "https://github.com/chenxiangcyr/spring-cloud-config-repo-demo//demo-dev.properties", 
            source: {
                jdbc.driverClassName: "com.mysql.jdbc.Driver", 
                jdbc.url: "jdbc:mysql://127.0.0.1:3306", 
                jdbc.username: "rootDev", 
                jdbc.password: "rootDev"
            }
        }
    ]
}

獲取配置信息

在這里,我們利用之前創建的項目 eureka-consumer,使得它可以通過分布式配置中心 config-server 來讀取配置。
首先在 pom.xml 中添加了如下的依賴:

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

隨后創建 bootstrap.properties ,用來配置配置中心:

# 開啟配置服務發現
spring.cloud.config.enabled=true

# 配置服務實例名稱
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server

spring.cloud.config.name=demo
spring.cloud.config.profile=dev
spring.cloud.config.label=master

eureka.client.serviceUrl.defaultZone=http://localhost:1234/eureka/

注意:上面這些屬性必須配置在 bootstrap.properties 中,這樣 config-server 中的配置信息才能被正確加載。

隨后,我們創建一個新的 ReadConfigController 來通過 @Value 注解的形式讀取配置:

@RestController
public class ReadConfigController {
    private final static Logger logger = LoggerFactory.getLogger(ReadConfigController.class);

    @Value("${jdbc.driverClassName}")
    String driverClassName;

    @Value("${jdbc.url}")
    String url;

    @Value("${jdbc.username}")
    String username;

    @Value("${jdbc.password}")
    String password;

    @GetMapping("/config")
    public String config() {

        logger.info("jdbc.driverClassName = " + driverClassName);
        logger.info("jdbc.url = " + url);
        logger.info("jdbc.username = " + username);
        logger.info("jdbc.password = " + password);

        return "success";
    }
}  

最后,重啟 eureka-consumer,訪問新創建的 Rest 接口 http://127.0.0.1:3001/config,可以在日志中看到,配置被成功讀?。?br>

配置被成功讀取

推送通知和 Spring Cloud Bus

在上面的示例中,有一個問題:我們通過 Git 修改來 demo-dev.properties 文件中的內容,但是更新后的內容并沒有被 eureka-consumer 獲取到。

現在我們來解決這個問題:
許多源代碼存儲庫提供程序(例如Github,Gitlab 或 Bitbucket)將通過 Webhook 通知您存儲庫中的更改。
可以通過提供商的用戶界面將 Webhook 配置為 URL 和一組感興趣的事件,例如:


設置 Webhook

設置 Webhook

流程如下圖所示:引用自 https://blog.csdn.net/mazhen1991/article/details/78513452

推送通知和 Spring Cloud Bus

對于配置中心 config-server,需要進行如下修改
添加如下的依賴到 pom.xml 中:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

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

安裝并啟動一個 RabbitMQ 實例,并在 application.properties 中配置 RabbitMQ 連接信息:

spring.rabbitmq.host=127.0.0.1
啟動兩個 config-server 實例連接到 RabbitMQ

對于 eureka-consumer,需要進行如下修改
添加如下的依賴到 pom.xml 中:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

application.properties 中配置 RabbitMQ 連接信息:

spring.rabbitmq.host=127.0.0.1

拓展閱讀


引用:
程序猿DD Spring Cloud基礎教程
Spring Cloud構建微服務架構:分布式配置中心【Dalston版】
Spring Cloud Dalston中文文檔

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容