Spring Boot + Spring Cloud 構建微服務系統(九):配置中心(Spring Cloud Config)

技術背景

現在微服務架構盛行,在分佈式系統中,項目日益龐大,子項目日益增多,每一個項目都散落着各類配置文件,且隨着服務的增長而不斷增多。此時,每每某一個基礎服務信息變動,都會致使一系列服務的更新和重啓,運維也是苦不堪言,並且還很容易出錯。因而,配置中心便由此應運而生了。java

目前市面上開源的配置中心有不少,像Spring家族的Spring Cloud Config, Apache的Apache Commons Configuration,淘寶的diamond, 百度的disconf, 360的QConf等等,都是爲了解決這類問題。當下Spring體系大行其道,咱們固然也優先選擇Spring Cloud Config了。git

Spring Cloud Config

Spring Cloud Config 是一套爲分佈式系統中的基礎設施和微服務應用提供集中化配置的管理方案,它分爲服務端與客戶端兩個部分。服務端也稱爲分佈式配置中心,它是一個獨立的微服務應用,用來鏈接配置倉庫併爲客戶端提供獲取配置信息。客戶端則是微服務架構中的各個微服務應用或基礎設施,它們經過指定的配置中心來管理服務相關的配置內容,並在啓動的時候從配置中心獲取和加載配置信息。web

Spring Cloud Config對服務端和客戶端中的環境變量和屬性配置 實現了抽象映射,因此它除了適用於 Spring 應用,也是能夠在任何其餘語言應用中使用的。Spring Cloud Config 實現的配置中心默認採用 Git 來存儲配置信息,因此使用 Spring Cloud Config 構建的配置服務器,自然就支持對微服務應用配置信息的版本管理,而且能夠經過 Git 客戶端工具很是方便的管理和訪問配置內容。固然它也提供了對其餘存儲方式的支持,好比:SVN 倉庫、本地化文件系統等。spring

實現案例

準備配置文件

首先在GIT下,新建config-reposity目錄,用來存放配置文件,以下圖所示,分別模擬了三個環境的配置文件。bootstrap

分別編輯三個文件的,配置 spring.config.hello 屬性的值爲 hello, this x env configurations.服務器

服務端實現

新建工程

新建 spring-cloud-conifg-server 工程。架構

添加依賴

除了Spring Cloud依賴以外,添加配置中心依賴包。app

pom.xml運維

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

啓動類

啓動類添加註解 @EnableConfigServer,開啓配置服務支持。分佈式

ConfigServerApplication.java

package com.louis.spring.cloud.config.server;

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

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

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

添加配置

修改配置文件,添加以下內容。若是是私有倉庫須要填寫用戶名密碼,若是是公開倉庫,能夠不配置密碼。

application.yml

server:
  port: 8551
spring:
  application:
    name: spring-cloud-config-server
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/liuge1988/spring-cloud-demo/         # 配置git倉庫的地址
          search-paths: config-repository                             # git倉庫地址下的相對地址,能夠配置多個,用,分割。
          username: username                                          # git倉庫的帳號
          password: password                                          # git倉庫的密碼

Spring Cloud Config也提供本地存儲配置的方式,只需設置屬性spring.profiles.active=native,Config Server會默認從應用的src/main/resource目錄下檢索配置文件。另外也能夠經過spring.cloud.config.server.native.searchLocations=file:D:/properties/屬性來指定配置文件的位置。雖然Spring Cloud Config提供了這樣的功能,可是爲了更好的支持內容管理和版本控制,仍是比較推薦使用GIT的方式。

測試效果

啓動應用,訪問 http://localhost:8551/spring-config/dev,返回結果以下。

啓動應用,訪問 http://localhost:8551/spring-config/pro,返回結果以下。

上述的返回的信息包含了配置文件的位置、版本、配置文件的名稱以及配置文件中的具體內容,說明server端已經成功獲取了git倉庫的配置信息。

訪問:http://localhost:8551/spring-config-dev.properties,返回結果以下。

修改一下dev配置文件內容以下(末尾加了一個 update):

spring.config.hello=hello, this dev env configurations update. 

再次訪問:http://localhost:8551/spring-config-dev.properties,返回結果以下。

發現讀取的是修改後提交的信息,說明服務端會自動讀取最新提交的數據。

倉庫中的配置文件會被轉換成相應的WEB接口,訪問能夠參照如下的規則:

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

以spring-config-dev.properties爲例子,它的application是spring-config,profile是dev。client會根據填寫的參數來選擇讀取對應的配置。

客戶端實現

新建工程

新建 spring-cloud-conifg-client 工程。

添加依賴

添加相關依賴,添加WEB是爲了測試接口。

pom.xml

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

添加配置

添加兩個配置文件以下。

application.yml

server:
  port: 8552
spring:
  application:
    name: spring-cloud-config-client

bootstrap.yml

spring:
  cloud:
    config:
      uri: http://localhost:8551/ # 配置中心的具體地址
      name: spring-config  # 對應{application}部分
      profile: dev  # 對應{profile}部分
      label: master  # 對應git的分支,若是配置中心使用的是本地存儲,則該參數無用

配置說明:

  • spring.cloud.config.uri:配置中心的具體地址
  • spring.cloud.config.name:對應{application}部分
  • spring.cloud.config.profile:對應{profile}部分
  • spring.cloud.config.label:對應git的分支。若是配置中心使用的是本地存儲,則該參數無用
  • spring.cloud.config.discovery.service-id:指定配置中心的service-id,便於擴展爲高可用配置集羣。

特別注意:

上面這些與spring cloud相關的屬性必須配置在bootstrap.yml中,這樣config部份內容才能被正確加載。

由於config的相關配置會先於application.yml,而bootstrap.yml的加載也是先於application.yml文件的。

啓動類

啓動類無需添加額外註解。

ConfigClientApplication.java

package com.louis.spring.cloud.config.client;

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

@SpringBootApplication
public class ConfigClientApplication {

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

控制器

添加一個 HelloController 控制器, 添加註解 @Value("${spring.config.hello}"),聲明hello屬性從配置文件讀取。

HelloController.java

package com.louis.spring.cloud.config.client.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
class HelloController {
    
    @Value("${spring.config.hello}")
    private String hello;

    @RequestMapping("/hello")
    public String from() {
        return this.hello;
    }
}

測試效果

前後啓動配置中心服務端和客戶端, 訪問 http://localhost:8552/hello,效果以下。

說明客戶端已經成功從服務端讀取了配置信息。

如今手動修改一下倉庫配置文件的內容,末尾加個數字 2,修改完成並提交。

 

 再次訪問 http://localhost:8552/hello,效果以下。

咱們發現返回結果並無讀取最新提交的內容,這是由於Spring Boot項目只有在啓動的時候纔會獲取配置文件的內容,雖然GIT配置信息被修改了,可是客戶端並無從新去獲取,因此致使讀取的信息仍然是舊配置。那麼該如何去解決這個問題呢?這就是咱們下一章要講的 Spring Cloud Bus。

配置中心服務化

到目前爲止,咱們的客戶端都是直接調用配置中心的server端來獲取配置文件信息。這樣客戶端和服務端的耦合性過高,若是server端要作集羣,客戶端只能經過原始的方式來路由,server端改變IP地址的時候,客戶端也須要修改配置,不符合Spring Cloud服務治理的理念。因此咱們須要將服務端也當作一個服務註冊到註冊中心,客戶端去註冊中心獲取配置中心服務就能夠了。

打開 spring-cloud-conifg-server,修改服務端POM,添加註冊中心依賴。

pom.xml

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

啓動類添加註解 @EnableDiscoveryClient,提供服務發現支持。

ConfigServerApplication.java

package com.louis.spring.cloud.config.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigServerApplication {

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

修改配置,添加服務註冊信息。

application.yml

server:
  port: 8551
spring:
  application:
    name: spring-cloud-config-server
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        serviceName: ${spring.application.name}    # 註冊到consul的服務名稱
    config:
      server:
        git:
          uri: https://gitee.com/liuge1988/spring-cloud-demo/     # 配置git倉庫的地址
          search-paths: config-repository                             # git倉庫地址下的相對地址,能夠配置多個,用,分割。
          username: username                                             # git倉庫的帳號
          password: password                                             # git倉庫的密碼

前後啓動註冊中心服務器,配置中心服務器, 訪問 http://localhost:8500,確認註冊中心註冊成功。

訪問 http://localhost:8551/config-server/dev,也能成功讀取配置,服務端就算改造好了。

打開 spring-cloud-conifg-client,修改服務端POM,添加註冊中心依賴。

pom.xml

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

啓動類添加註解 @EnableDiscoveryClient,提供服務發現支持。

ConfigClientApplication.java

package com.louis.spring.cloud.config.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class ConfigClientApplication {

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

修改配置文件,移除uri的直接地址配置,開啓服務發現並配置serviceId爲註冊中心服務器的服務名稱。

bootstrap.yml

spring:
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        serviceName: spring-cloud-config-client    # 註冊到consul的服務名稱
    config:
      discovery:
        enabled: true  # 開啓服務發現
        serviceId: spring-cloud-config-server # 配置中心服務名稱
      name: spring-config  # 對應{application}部分
      profile: dev  # 對應{profile}部分
      label: master  # 對應git的分支,若是配置中心使用的是本地存儲,則該參數無用

啓動客戶端,訪問 http://localhost:8552/hello,成功讀取配置信息,說明客戶端也改造完成了。

 

源碼下載

碼雲:https://gitee.com/liuge1988/spring-cloud-demo.git


做者:朝雨憶輕塵
出處:https://www.cnblogs.com/xifengxiaoma/ 版權全部,歡迎轉載,轉載請註明原文做者及出處。

相關文章
相關標籤/搜索