Spring Cloud(十四)Config 配置中心與客戶端的使用與詳細


前言

在上一篇 文章 中我們直接用了本應在本文中配置的Config Server,對Config也有了一個基本的認識,即

Spring Cloud Config 是一種用來動態獲取Git、SVN、本地的配置文件的一種工具

在上文中我們使用Config用來實現 動態路由 的功能,就是使用的Git的方式

源碼見 https://github.com/hellxz/SpringCloudLearn

快速入門

1. Config Server 的搭建

新建一個模塊名為ConfigServer,pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.cnblogs.hellxz</groupId>
    <artifactId>ConfigServer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-parent</artifactId>
        <version>Dalston.SR5</version>
        <relativePath/>
    </parent>

    <dependencies>
        <!--Spring Cloud Config 服務端依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

配置文件沒什么好說的,其中因為我們不需要將這個項目注冊到 注冊中心 ,所以我們只需添加Config Server的依賴

需要注意的是:之前我們一般都是用的各種starter,而這個config server不是spring-cloud-starter-config-server而是spring-cloud-config-server

在java目錄下添加主類ConfigServerApp

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.config.server.EnableConfigServer;

/**
 * 這里沒有使用SpringBootApplication或SpringCloudApplication注解,會報錯
 * 原因也很簡單,我們的java源碼目錄下沒有目錄,我們手動加一個也就正常了,
 * 為了寫點體會和這里沒必要用到包和類,所以使用這種方式
 */
@EnableConfigServer
@SpringBootConfiguration
@EnableAutoConfiguration
public class ConfigServerApp {

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

其中我們只需要提供@EnableConfigServer注解來開啟config 的server功能

在resources下添加一個bootstrap.yml

server:
  port: 7001

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/hellxz/SpringCloudlearn
          search-paths: config-repo
          username: username  #賬號密碼寫真實的快一些我覺得,不使用也能訪問有點慢
          password: password

其中spring.cloud.config.server.git.uri指向的是配置文件所在的git項目uri

search-paths指定的是匹配查詢的路徑名

username和password是訪問倉庫的用戶名和密碼,寫自己的好象快一些,還有用碼雲也會快一些,因為網絡長城

現在項目就配置好了,我們需要提供配置文件了,我們在SpringCloudLean下創建一個普通目錄config-repo,在這個下面加入幾個測試用的配置文件,這里加上五個測試文件,分別如下:

hellxztest.yml

from: default-environment-1.0

hellxztest-dev.yml

from: dev-environment-1.0

hellxztest-prod.yml

from: prod-environment-1.0

hellxztest-stable.yml

from: stable-environment-1.0

dynamic-route-zuul.yml

zuul:
  routes:
    service-provider:
      path: /service/**
      serviceId: eureka-service

前三個是普通的測試文件,最后一個是上一篇文章中做動態路由實驗中用到的文件

這個文件的目錄也可以創建一個其它的項目提到git上

將config-repo提交到github上,或者你自己的碼雲、gitlab等均可,修改之前的uri進行測試.

測試

只需啟動ConfigServer項目即可。

使用postman進行測試

其它也是一樣的,我們試一下動態路由的配置

測試默認的配置文件

接下來講講這些url為什么是這樣的

配置規則詳解

還記得最開始我們建的那幾個測試文件的命名規則么?

  • hellxztest.yml
  • hellxztest-dev.yml
  • hellxztest-stable.yml
  • hellxztest-prod.yml

這里的application可以自定義為其它的名稱,這里可以用應用的名稱,即應用名,后邊的dev、stable、prod這些都可以視為一個應用下多個不同的配置文件,可以當做環境名,以下均用環境名代稱。

Config支持我們使用的請求的參數規則為:

  • / { 應用名 } / { 環境名 } [ / { 分支名 } ]
  • / { 應用名 } - { 環境名 }.yml
  • / { 應用名 } - { 環境名 }.properties
  • / { 分支名 } / { 應用名 } - { 環境名 }.yml
  • / { 分支名 } / { 應用名 } - { 環境名 }.properties

注意:

  1. 第一個規則的分支名是可以省略的,默認是master分支
  2. 無論你的配置文件是properties,還是yml,只要是應用名+環境名能匹配到這個配置文件,那么就能取到
  3. 如果是想直接定位到沒有寫環境名的默認配置,那么就可以使用default去匹配沒有環境名的配置文件
  4. 使用第一個規則會匹配到默認配置
  5. 如果直接使用應用名來匹配,會出現404錯誤,此時可以加上分支名匹配到默認配置文件
  6. 如果配置文件的命名很由多個-分隔,此時直接使用這個文件名去匹配的話,會出現直接將內容以源配置文件內容直接返回,內容前可能會有默認配置文件的內容(已測試)

此時我們查看ConfigServer的終端輸出,我們很容易發現他的工作原理:

使用git clone 方式,將配置文件拉取到本地,將配置文件的信息傳輸給接收端

斷網測試一下

測試正常,配置文件信息依舊被請求獲取到了,該配置信息來自Config Server本地

客戶端配置映射與動態刷新

1. 創建Config Client

為了更直觀地測試客戶端的配置,這里新建一個模塊ConfigClient,pom如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.cnblogs.hellxz</groupId>
    <artifactId>ConfigClient</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-parent</artifactId>
        <version>Dalston.SR5</version>
        <relativePath/>
    </parent>

    <dependencies>
        <!--Spring Cloud Config 客戶端依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!-- web的依賴,必須加 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Spring Boot Actuator,感應服務端變化-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

</project>

創建名為com.cnblogs.hellxz的包,新建主類ConfigClientApp

package com.cnblogs.hellxz;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConfigClientApp {

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

在剛才的包下加一層controller的包,加一個用來展示服務端返回的from的值的TestController

package com.cnblogs.hellxz.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 當有請求/fresh節點的時候,會重新請求一次ConfigServer去拉取最新的配置文件
 * 請求/fresh需要有幾點要求:1.加actuator的依賴 2.SpringCloud1.5以上需要設置 management.security.enabled=false
 * 這個Controller的作用是查看from這個key的值
 */
@RestController
@RefreshScope //開啟更新功能
@RequestMapping("api")
public class TestController {

    @Value("${from}")
    private String fromValue;

    /**
     * 返回配置文件中的值
     */
    @GetMapping("/from")
    @ResponseBody
    public String returnFormValue(){
        return fromValue;
    }
}

@RefreshScope是為了可以動態刷新這個Controller的Bean

接下來在resources目錄下創建bootstrap.yml

spring:
  application:
    name: hellxztest                     #指定了配置文件的應用名
  cloud:
    config:
      uri: http://localhost:7001/        #Config server的uri
      profile: dev                       #指定的環境
      label: master                      #指定分支
server:
  port: 7002
management:
  security:
    enabled: false     #SpringBoot 1.5.X 以上默認開通了安全認證,如果不關閉會要求權限

注意:

  1. 參數:
  • spring.application.name:對應文件規則的應用名
  • spring.cloud.config.profile:對應環境名
  • spring.cloud.config.label:對應分支名
  • spring.cloud.config.uri:對應Config Server開放的地址
  1. 如果要用到動態刷新,SpringBoot 1.5版本以上需要使用management.security.enabled=false

2. 測試

Config Server 和 Config Client 這兩個都沒有注冊到Eureka注冊中心,這里只需要啟動這兩個項目

我們看到Config Client項目在啟動的時候請求一次Config Server

以下圖片看不清的請復制圖片地址訪問查看

而且我們還在終端輸出中看到了匹配的/refresh節點被Mapped了,請求的方法是Post

請求一下http://localhost:7002/api/from

我們看到from現在對應的值是dev-environment-1.0,這里我們去github或本地改一下hellxztest-dev.yml,將1.0改為2.0並提交git,我們再去訪問http://localhost:7002/api/from

接下來測試一下/fresh接口,注意這里要用post方法進行訪問

此時我們還需要調用一次http://localhost:7002/api/from

可以看到from的值的確在Config Client中改變了,當中並沒有重啟Config Client,刷新配置功能測試通過。

一邊看書一邊做實驗,以為書中這塊沒有動態刷新了,特意往后看了看,結果發現這塊作者還真的有寫……我……我是想到這塊應該有一個刷新的機制,先參考學習了@純結的微笑的博文springcloud(七):配置中心svn示例和refresh ,然后配置的項目……

一般我們不能每次修改配置都手動刷新(post方法調用/refresh),可以與github之類的webhook進行配合,如果有修改就發起post請求/refresh就可以了,svn也有類似的hook機制,這里就不多講了。

服務端詳解

1. 基礎架構

根據上邊的結構圖,我們可以看到幾個必要的元素:

  • 遠程git倉庫:用來存儲配置文件的地方,多環境配置文件使用 hellxztest-{環境名}.yml
  • Config Server:分布式配置中心,指定了git倉庫uri搜索路徑訪問賬號密碼
  • 微服務應用:配置客戶端(Config Client),指定應用名配置中心url環境名分支名

2. 啟動流程:

  1. 微服務應用啟動,根據bootstrap.yml(properties)中配置的應用名(application)、環境名(profile)、分支名(label),向Config Server請求配置信息
  2. Config Server 根據自己bootstrap.yml(properties)中的Git(或SVN)倉庫信息加上客戶端傳來的配置定位信息去查配置信息的路徑
  3. Config Server 執行git clone命令,將配置信息下載到本地Git倉庫中,將配置信息加載到Spring的ApplicationContext讀取內容返回給客戶端(微服務應用)
  4. 客戶端將內容加載到ApplicationContext,配置內容的優先級大於客戶端內部的配置內容,進行忽略

特殊情況: 當Config Server因為網絡原因無法連接到Git或SVN時,客戶端的請求過來后,會先連接Git或SVN,如果沒連上,就使用本地倉庫的配置文件內容進行返回給客戶端

3. Git配置倉庫

本地倉庫

Spring Cloud Config默認使用Git,對Git的配置也最簡單,這里Config Server只用到了uri、username、password這三個參數就可以讀取配置了,通過Git的版本控制可以使Config Server適應特殊的場景。

測試時我們也可以使用本地倉庫的方式,使用file://前綴,那么uri的配置就可以寫作

spring:
  cloud: 
    config: 
      server: 
        git: 
          uri: file://${user.home}/config-repo

注意:

  1. Windows系統需要使用file:///前綴
  2. ${user.home}代表當前用戶的家目錄

占位符配置URI

{application}{profile}{label}這些占位符除了標識配置文件規則外,還可以對Git的uri配置,

如:spring.cloud.config.server.git.uri=https://github.com/hellxz/SpringCloudlearn/config-repo/{application}

此時spring.application.name的值會填充到這個uri中,從而達到動態獲取不同位置的配置

匹配並配置多個倉庫

Spring Cloud Config Server除了使用{應用名}/{環境名}來匹配配置倉庫外,還支持通過帶有通配符的表達式來匹配。

當有多個匹配規則的時候,可以用逗號分隔多個{應用名}/{環境名}配置規則。

以官方文檔例子加減舉例:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo   #默認的倉庫
          repos:
            simple: https://github.com/simple/config-repo
            special:
              pattern: special*/dev*,*special*/dev*
              uri: https://github.com/special/config-repo
            local:
              pattern: local*
              uri: file:/home/configsvc/config-repo
            test: 
              pattern: 
                - '*/development'
                - '*/staging'
              uri: https://github.com/development/config-repo

如果{應用名}/{環境名}不能匹配到倉庫,那么就在默認的uri下去查找配置文件。

上邊的例子中,

  • simple 倉庫自動匹配到 simple/*
  • special 倉庫的pattern,第一個是應用名以special開頭,環境名以dev開頭;第二個是應用名包含special,環境名以dev開頭;多個匹配到同一uri的pattern用逗號分割
  • local 倉庫的的pattern也會自動補全為local*/*
  • test倉庫中的 pattern 是以通配符開始的,需要使用單引號

注意:配置多個倉庫時,Config Server 在啟動時會直接克隆第一個倉庫的配置庫,其他配置庫只有請求時才會clone到本地

子目錄存儲

通過spring.cloud.config.server.git.searchPaths來定位到Git倉庫的子目錄中,相當於在uri后加上searchPaths的目錄。

searchPaths參數的配置也支持使用{應用名}、{環境名}、{分支名}占位符

比如spring.cloud.config.server.git.searchPaths={應用名},通過這樣的配置,我們能讓每一個應用匹配到自己的目錄中。

舉例:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          searchPaths: '{application}'

訪問權限

使用Git倉庫的時候,使用HTTP認證需要使用username和password屬性來配置賬戶

舉例

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          username: trolley
          password: strongpassword

還可以使用SSH認證,Config Server本地的.ssh文件或使用私鑰等進行配置,此處僅為提出這個用法,不作深究,使用方法見http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html#_git_ssh_configuration_using_properties

4. SVN配置倉庫

除了默認使用Git外,還可以使用SVN進行配置,如下:

在pom.xml中加入SVN的依賴配置,這里沒寫版本號,Spring Cloud中包含其版本號

        <!--SVN-->
        <dependency>
            <groupId>org.tmatesoft.svnkit</groupId>
            <artifactId>svnkit</artifactId>
        </dependency>

在bootstrap.yml加入

spring:
  cloud:
    config:
      server:
        svn:
          uri: http://192.168.0.1/svn/repo/config-repo
          username: username
          password: password
        default-label: trunk
  profiles:
    active: subversion

和Git版本稍有區別,需要顯示聲明subversion,其他使用方法同Git

5. 本地倉庫

使用版本控制方式將配置文件clone到本地,往往都是克隆到一些臨時目錄中,但是操作系統往往會清理這些臨時目錄,這可以導致一些我們不期待的情況,比如丟配置,為了避免出現這種問題,可以通過spring.cloud.config.server.svn.basedir去更改本地倉庫的位置。

6. 本地文件系統

不同於Git和SVN以及他們的本地倉庫的存儲方式,Spring Cloud Config 提供了本地文件系統的存儲方式來保存配置信息,實現方式很簡單,設置屬性spring.profiles.active=native,Config Server會從應用的src/main/resources目錄下搜索配置文件。如果需要指定配置文件的路徑,可以通過spring.cloud.config.server.native.searchLocations屬性來指定具體配置文件位置。

放在本地應用中不如直接配置在bootstrap.yml中,這樣一想,這個Config Server端就沒什么用了,雖然有這個功能,但還是推薦使用Git和SVN倉庫的方式。

7. 健康監測

配置好了Git或SVN之后,為了能確保能連通倉庫,我們需要為其實現健康監測功能,來判斷Git或SVN倉庫是否可以訪問

我們配置了spring.cloud.config.server.git.uri,而且依賴了spring-boot-actuator的依賴,會自動mapped到/health的端點,我們可以訪問測試一下

這里沒有配具體的倉庫路徑,不然會顯示出更多的信息

如果我們無法連接到配置倉庫的uri那么status就會變成DOWN

org.springframework.cloud.config.server.config包中有一個ConfigServerHealthIndicator的健康檢測器,這個檢測器會不斷地檢查配置的uri是否可以連通。

如果不想使用這個健康檢測器,也可以通過使用spring.cloud.config.server.health.enabled=false來禁用它。

8. 屬性覆蓋

Config Server提供一個叫Property Overrides屬性覆蓋的功能,通過spring.cloud.config.server.overrides屬性來設置鍵值對的參數,這些參數會以Map形式加載到所有Config Client的配置中。

官方舉例:

spring:
  cloud:
    config:
      server:
        overrides:
          foo: bar

通過屬性覆蓋配置的參數不會被Config Client修改,並且Config Client獲取配置信息時就會得到這些信息,使用這種特性可以方便我們為客戶端應用配置一些共同屬性或默認屬性。這些屬性不是強制的,可以通過改變客戶端中的更高優先我級的配置方式來選擇是否使用這些屬性覆蓋的默認值。

9. 安全保護

配置中心存儲的內容很敏感,所以必需做一些安保措施,使用Spring Security更方便一些。

只需要引入依賴並配置用戶名和密碼

        <!--Spring Security依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-security</artifactId>
        </dependency>

默認情況下會得到一名為user的用戶,並在配置中心啟動的時候在log中打印出來隨機密碼,當然大多數情況下我們不會使用這個隨機密碼,我們可以在配置文件中指定用戶和密碼

security: 
  user:
    name: user
    password: xxxxxxx

通過上邊的配置,配置中心已經開啟了安全保護,這時候連接配置中心的客戶端沒有密碼的情況下會返回401錯誤

只需要在客戶端中加入賬號密碼來通過安全校驗,舉例

spring: 
  cloud: 
    config: 
      username: user
      password: xxxxxxx

10. 加密解密

微服務開發中往往都是所屬組織成員自行維護,在配置文件中會有很多敏感信息,比如數據庫密碼等,這些信息如果以明文存儲和傳輸是很危險的,為解決這個問題,Config提供了對屬性加密解密的功能,只需要在敏感信息的值加密后加上前綴{cipher},這主要是為了防止密文被用作密碼並意外泄露。ps: 防的就是開發人員。。

重要:要使用加密和解密功能,您需要在JVM中安裝全功能JCE(默認情況下不包括它)。您可以從Oracle下載“Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files”並按照安裝說明進行操作(實質上,您需要將JRE lib / security目錄中的兩個策略文件替換為您下載的那些)。

JCE for JDK8下載地址http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

注意:上邊說的是官方的說法,但是我發現一個很氣的事實是我下載好這JCE的文件后,發現jdk1.8中已經有了這些文件,如下圖

可能是1.8自帶了這些吧,按Spring Cloud 文檔中的說法,把unlimited下的兩個jar包復制到{JAVA_HOME}/jre/lib/security目錄下,這里當然也沒有自帶的JCE這兩個包去被覆蓋,limited和unlimited區別在於limited對加密解密的長度有限制。

用數據源舉例:

spring:
  datasource:
    username: dbuser
    password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

.yml配置文件需要使用單引號括起來要解密的內容,.properties文件中的加密值不得用引號括起來。否則,該值不會被解密。

相關端點

完成了JCE的安裝后,可以嘗試啟動配置中心,Spring Cloud 暴露出了幾個端點

  • /encrypt/status:查看加密功能狀態的端點
  • /key:查看密鑰的端點
  • /encrypt:對請求的body內容進行加密的端點
  • /decrypt:對請求的body內容進行解密的端點

在沒有設置密鑰的時候,訪問/encrypt/status端點會出現

{
    "description":"No key was installed for encryption service",
    "status":""
}

在bootstrap.yml中設置密鑰(對稱性密鑰)

encrypt:
  key: hellxz

這里發現如果放在application.yml中,調用/encrypt/status還是上邊的情況,放到bootstrap.yml中正常了

重啟Config Server,使用/encrypt端點測試加密效果:

/decrypt解密測試:

非對稱加密

非對稱加密相對對稱加密的密鑰生成與配置更加復雜,耗時也更多,但是更安全。

這里我們使用jdk自帶的keytool工具來生成證書,它的位置在%JAVA_HOME%\bin\keytool.exe

生成密鑰的命令如下,請酌情修改:

PS C:\Program Files\java\jdk1.8.0_161\bin> keytool -genkeypair -alias config-server -keyalg RSA -keystore D:\\config-server.keystore
輸入密鑰庫口令:
再次輸入新口令:
您的名字與姓氏是什么?
  [Unknown]:  Hellxz Zhang
您的組織單位名稱是什么?
  [Unknown]:  SN
您的組織名稱是什么?
  [Unknown]:  SN
您所在的城市或區域名稱是什么?
  [Unknown]:  JiNan
您所在的省/市/自治區名稱是什么?
  [Unknown]:  ShanDong
該單位的雙字母國家/地區代碼是什么?
  [Unknown]:  ZH
CN=Hellxz Zhang, OU=SN, O=SN, L=JiNan, ST=ShanDong, C=ZH是否正確?
  [否]:  y

輸入 <config-server> 的密鑰口令
        (如果和密鑰庫口令相同, 按回車):

Warning:
JKS 密鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore D:\\config-server.keystore -destkeystore D:\\conf
ig-server.keystore -deststoretype pkcs12" 遷移到行業標准格式 PKCS12。

這里使用的是PowerShell,在win下測試的,這樣操作后,在D盤生成了config-server.keystore的文件,我們將這個文件放到Config Server 的resources下(classpath),然后在bootstrap.yml加入相關配置信息

encrypt:
  key: hellxz
  key-store:
    location: config-server.keystore
    alias: config-server
    password: hellxz
    secret: hellxz

生成的時候密碼都是盲輸的,我都輸的hellxz,如有修改,請用自己輸入的

加密測試

解密測試:

圖片不清晰請復制圖片地址,地址欄訪問查看

11. 高可用配置

為了實現配置中心的高可用,主要有兩種方式

  1. 傳統模式:不需做任何額外配置,起多個配置中心服務,所有配置中心都指向同一個Git倉庫,客戶端通過負載均衡進行調用配置中心服務,從而實現服務的高可用
  2. 服務模式:將配置中心注冊為微服務到注冊中心,通過Eureka的服務治理進行負載均衡,而且也實現了自維護,這塊在后邊的客戶端詳解中講。

客戶端詳解

1. URI指定配置中心

Spring Clout Config的客戶端在啟動的時候,默認會從工程的classpath下加載配置信息並啟動應用,只有配置了spring.cloud.config.uri的時候,客戶端才會嘗試連接Config Server拉取配置信息並初始化Spring環境配置。我們必須將uri這個屬性參數配置到bootstrap.yml(或.properties)中,這個配置文件的優先級大於application.yml和其它文件,這樣才能保證能正確加載遠程配置。啟動的時候客戶端會去連接uri屬性的值。

舉例:

spring: 
  application:
    name: hellxztest
  cloud:
    config:
      uri: http://localhost:7001/
      profile: dev

例子中使用application.name和profile定位配置信息

2. 服務化配置中心

服務端詳解那一塊說過可以把配置中心注冊到注冊中心,通過服務發現來訪問Config Server拉取Git倉庫中的配置信息。

下面的內容需要改造ConfigServer和ConfigClient

為ConfigServer和ConfigClient的pom.xml中分別加入Eureka的依賴

        <!-- Spring Cloud Eureka的依賴 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

在上邊說過,bootstrap.yml的優化級大於application.yml,這里我們需在將這兩個服務都注冊到注冊中心,所以我選擇在ConfigServer的resources下創建一個application.yml,在其中配置連接注冊中心的通用信息

applicaiton.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1111/eureka/

將這個applicaiton.yml 的內容復制到ConfigClient的resources下的bootstrap.yml中。

依賴有了,注冊中心的地址也有了,別忘了將這兩個模塊的主類加上@EnableDiscoveryClient

完成這一步我們可以先啟動注冊中心、ConfigServer、ConfigClient 看一看是否注冊成功,如圖,

ConfigServer至此配置完畢。接下來我們為客戶端使用服務發現的方式去調用ConfigServer

只需要在ConfigClient的bootstrap.yml中注掉spring.cloud.config.uri那一項,spring.cloud.discovery.enabled=truespring.cloud.discovery.serviceId=config-server,為了更直觀,下面把整個ConfigClient的bootstrap.yml粘出來

spring:
  application:
    name: hellxztest                     #指定了配置文件的應用名
  cloud:
    config:
#      uri: http://localhost:7001/    #Config server的uri
      profile: dev                          #指定的環境
      label: master                        #指定分支
      discovery:
        enabled: true                     #開啟配置服務發現
        serviceId: config-server        #配置中心服務名
server:
  port: 7002
management:
  security:
    enabled: false     #SpringBoot 1.5.X 以上默認開通了安全認證,如果不關閉會要求權限
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1111/eureka/

重啟ConfigClient項目,我們之前提供了一個接口/api/from,這個接口會返回git上hellxztest-dev.yml中的from參數的值,現在我們只要調通這個接口就說明我們使用服務發現功能連接配置中心成功。

測試成功,服務化配置中心配置完成。

3. 失敗快速響應與重試

Spring Cloud Config的客戶端會預先加載很多配置信息,然后才開始連接Config Server進行屬性的注入,當應用復雜的時候,連接ConfigServer時間過長會直接影響項目的啟動速度,我們還希望能知道Config Client 是否能從Config Server中取到信息。此時,只需在bootstrap.yml(.properties)中配置屬性spring.cloud.config.failfast=true即可。

關閉Config Server,重啟Config Client,項目直接報錯無法啟動

java.lang.IllegalStateException: Could not locate PropertySource and the fail fast property is set, failing
	…… 省略其他錯誤信息 …… 

直接失敗似乎代價有些高,所以Config客戶端還提供了自動重試的功能,開啟前請確認spring.cloud.config.failfast=true參數已經配置,然后為ConfigClient的pom.xml增加spring-retry和spring-boot-starter-aop的依賴,如下:

        <!-- 連接配置中心重試的依賴 -->
        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

只需加入如上兩個依賴就能實現自動重試,當第6次重試失敗之后,那么就會上邊那個快速失敗報的錯誤

如果對最大重試次數和重試間隔等設置不滿意,可以通過下面有參數進行調整。

spring:
  cloud:
    fail-fast: true                 #快速失敗
    retry:
      initial-interval: 1100        #首次重試間隔時間,默認1000毫秒
      multiplier: 1.1D              #下一次重試間隔時間的乘數,比如開始1000,下一次就是1000*1.1=1100
      max-interval: 2000            #最大重試時間,默認2000
      max-attempts: 3               #最大重試次數,默認6次

這塊書中把inital-interval和multiplier的作用寫反了,請注意。

結束

看了上一篇文章的可能等着急了,本人看書很慢,最近有在學半音階口琴,這些文字內容都是工作清閑時候寫成的,相比上次更新已有5天,所有文字均為手打,全文7k多字,書中寫的表達好的地方直接就引用了,再次感謝《Spring Cloud微服務實戰》的作者

本文引用內容自:

下一節 繼續學習 Spring Cloud Bus,請大家耐心等待

手打不易,本文內容如需轉載請注明出處


免責聲明!

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



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