天天看點

Spring Cloud實戰系列(六) - 分布式配置中心Spring Cloud Config前言正文參考

前言

在 分布式系統 中,由于服務數量巨多,為了友善 服務配置檔案 的 統一管理 和 實時更新,是以需要 分布式配置中心 元件。

Spring Cloud

提供的 分布式配置中心 元件是

Spring Cloud Config

,它支援将 配置服務 放在配置服務的 記憶體 中(即 本地),也支援放在 遠端

Git

倉庫中。

Spring Cloud Config

提供了兩個角色,其一是

Config Server

,其二是

Config Client

正文

1. Config Server從本地讀取配置檔案

建立一個新的

Spring Boot

項目子產品,取名為

config-server

,它的

pom.xml

配置如下:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>io.github.ostenant.springcloud</groupId>
    <artifactId>config-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>config-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.RELEASE</spring-cloud.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
           

在應用啟動類上使用 注解

@EnableConfigServer

開啟 配置伺服器。

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

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

需要在程式的 配置檔案

application.properties

裡面進行如下配置。通過

spring.profile.active=native

來配置

Config Server

從 本地讀取配置,讀取的路徑為

Classpath

下的

shared

目錄。

server:
  port: 8769
spring:
  application:
    name: config-server
  profiles:
    active: native
  cloud:
    config:
      server:
        native:
          search-locations: classpath:/shared
           

src/main/resources

目錄下建立

shared

檔案夾,在

shared

檔案夾下建立一個

config-client-dev.yml

檔案。

server:
  port: 8762
foo: foo version 1
           

運作

ConfigServerApplication

main()

方法,在

8769

端口啟動

Config Server

應用程式。

2. 建構Config Client

建立一個

Spring Boot

項目子產品,取名為

config-client

,它的

pom.xml

配置如下:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>io.github.ostenant.springcloud</groupId>
    <artifactId>config-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>config-client</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <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>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
           

resources

目錄下建立

bootstrap.yml

檔案,因為

bootstrap

相對于

application

具有 優先的執行順序。

變量

{spring.application.name}

{spring.profiles.active}

,兩者使用

“-”

相連,作為

Config Client

Config Server

讀取的 配置檔案名。

bootstrap.yml

spring:
  application:
    name: config-client
  cloud:
    config:
      uri: http://localhost:8769
      fail-fast: true # 讀取沒有成功,執行快速失敗
  profiles:
    active: dev
           

配置一個接口,用于測試 讀取配置檔案 的

foo

變量,并通過

API

接口傳回用戶端。

@RestController
@SpringBootApplication
public class ConfigClientApplication {

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

    @Value("${foo}")
    private String foo;

    @RequestMapping(value = "/foo")
    public String foo(){
        return foo;
    }
}
           

啟動

config-client

應用程式,通路

http://localhost:8762/foo

,服務端的響應資料如下:

foo version 1

可見

config-client

成功地從

config-server

項目的

shared

本地檔案目錄 讀取到 配置檔案

config-client-dev.yml

中的

foo

變量。

3. Config Server從遠端Git倉庫讀取配置檔案

修改

config-server

的配置檔案

application.yml

,代碼如下.

server:
  port: 8769
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://coding.net/ostenant/config-repo
          search-paths: test
          username: [email protected]
          password: xxxx
      label: master
           

如果

Git

倉庫為 公開倉庫,可以不填寫 使用者名 和 密碼;如果是 私有倉庫 則需要填寫,本例子配置了一個 私有倉庫。

配置 解釋
spring.cloud.config.server.git.uri 配置git倉庫位址
spring.cloud.config.server.git.searchPaths 配置倉庫路徑
spring.cloud.config.label 配置倉庫的分支
spring.cloud.config.server.git.username 通路git倉庫的使用者名
spring.cloud.config.server.git.password 通路git倉庫的使用者密碼

遠端倉庫

https://coding.net/ostenant/config-repo

中有個 名為

config-client-dev.properties

的 配置檔案,裡面配置有一個屬性:

foo = foo version 2
           

重新啟動應用程式

config-server

config-client

,再次通路

http://localhost:8762/foo

,服務端的響應資料如下:

foo version 2

可見,

config-server

從遠端

Git

倉庫讀取了 配置檔案,進一步

config-client

config-server

讀取了相關的 配置屬性。

4. 建構高可用的Config Server

将 配置中心

config-server

做成一個 微服務,并且将其 叢集化,進而實作 高可用。

4.1. 改造Config Server

Config Server

中引入

Eureka

用戶端的 起步依賴

spring-cloud-starter-eureka

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

在應用的 啟動類 上加上 注解

@EnableEurekaClient

,将

Config Server

注冊到

Eureka Server

上面。

在配置檔案

application.yml

加入 服務注冊位址:

eureka:
  client:
    service-url:
      defaultZone: http://locahost:8761/eureka/
           

4.2. 改造Config Client

同樣的在

Config Client

中引入

Eureka

用戶端的 起步依賴

spring-cloud-starter-eureka

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

在應用的 啟動類 上加上 注解

@EnableEurekaClient

,将

Config Client

注冊到

Eureka Server

上面。

在配置檔案

application.yml

加入 服務注冊位址:

eureka:
  client:
    service-url:
      defaultZone: http://locahost:8761/eureka/
           

在配置檔案

application.yml

加入相關配置,從

service-id

config-server

的 配置服務 讀取相關 配置檔案。

spring:
  application:
    name: config-client
  cloud:
    config:
      fail-fast: true
      discovery:
        enabled: true
        service-id: config-server
  profiles:
    active: dev
server:
  port: 8762
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
           

重新啟動應用程式

config-server

config-client

,再次通路

http://localhost:8762/foo

,服務端的響應資料如下:

foo version 2

隻需要啟動多個

config-server

執行個體,即可搭建一個 高可用 的

config-server

叢集。

5. 使用Spring Cloud Bus重新整理配置

Spring Cloud Bus

将 分布式節點 通過輕量級的 消息代理 連接配接起來。它可以用于 廣播配置檔案 的更改或者 服務之間 的通訊,也可以用于 監控。在 分布式配置檔案 被更改後,可以通過

Spring Cloud Bus

通知各個微服務中的即時重新整理 本地配置。

5.1. 改造config-client

config-client

pom.xml

裡面加入 起步依賴

spring-cloud-starter-bus-amqp

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

在項目的配置檔案

application.yml

檔案中添加

RabbitMQ

的相關配置,包括

RabbitMQ

的 位址、端口、使用者名 和 密碼。為了友善驗證,将

management.security.enabled

改為

false

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
management.security.enabled=false
           

最後,在需要更新屬性的 配置類 上加

@RefreshScope

注解。

@RefreshScope
@RestController
@SpringBootApplication
public class ConfigClientApplication {

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

    @Value("${foo}")
    private String foo;

    @RequestMapping(value = "/foo")
    public String foo(){
        return foo;
    }
}
           

依次啟動應用,啟動兩個

config-client

執行個體,端口 分别為

8762

8763

。啟動完成後,通路

http://localhost:8762/foo

或者

http://localhost:8763/foo

,服務端響應資料如下:

foo version 2

更改遠端

Git

倉庫 配置檔案 的

config-client-dev.properties

,将

foo

的值改為

“foo version 3”

通路

http://localhost:8762/bus/refresh

請求 重新整理配置,設定

“destination”

參數為 待重新整理 屬性的 服務名稱。例如

“http://localhost:8762/bus/refresh?destination=config-client:**”

,即 重新整理服務名 為

config-client

的所有 服務執行個體。

Spring Cloud實戰系列(六) - 分布式配置中心Spring Cloud Config前言正文參考

再次通路

http://localhost:8762/foo

http://localhost:8763/foo

,服務端響應資料如下:

foo version 3

測試結果表明,

/bus/refresh

通知服務名為

config-client

的所有執行個體 重新整理 了本地的

foo

屬性配置。

參考

  • 方志朋《深入了解Spring Cloud與微服務建構》

歡迎關注技術公衆号: 零壹技術棧

Spring Cloud實戰系列(六) - 分布式配置中心Spring Cloud Config前言正文參考

本帳号将持續分享後端技術幹貨,包括虛拟機基礎,多線程程式設計,高性能架構,異步、緩存和消息中間件,分布式和微服務,架構學習和進階等學習資料和文章。

繼續閱讀