SpringCloud系列教程 | 第六篇:Spring Cloud Config Github配置中心 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如無特殊說明,本系列教程全採用以上版本 隨著分散式項目越來越大,勤勞的程式猿們會開始面臨 ...
SpringCloud系列教程 | 第六篇:Spring Cloud Config Github配置中心
Springboot: 2.1.6.RELEASE
SpringCloud: Greenwich.SR1
如無特殊說明,本系列教程全採用以上版本
隨著分散式項目越來越大,勤勞的程式猿們會開始面臨一個挑戰,配置文件會越來越繁雜,雖然spring提供了一個雞肋版的解決方案,spring.profiles.active,在大型的分散式項目體系中,聊勝於無吧,手動維護配置文件的痛苦,生產,UAT,測試,開發環境的隔離,額外的配置文件,如:logback.xml日誌的配置文件,bootstrap.properties配置文件,當系統中有幾十個服務,相應的會有上百個配置文件,簡直就是史詩級的災難大片,每次發佈上線,都要手動去檢查配置文件,相應的服務都需要重啟,那麼,有沒有一種方案,可以自動更新配置,並且對版本做出相應的控制,恰好,springcloud為我們提供了這樣一種工具,雖然很多方面都還不完善,配置能力比較弱,但是也給我們提供了一種思路。
市面上有很多配置中心,BAT每家都出過,360的QConf、淘寶的diamond、百度的disconf都是解決這類問題。國外也有很多開源的配置中心Apache Commons Configuration、owner、cfg4j等等。這些開源的軟體以及解決方案都很優秀,也存在這樣或者那樣的缺陷。今天我們要瞭解的Spring Cloud Config,可以無縫的和spring體系相結合,夠方便夠簡單顏值高。
1. Spring Cloud Config
在介紹Spring Cloud Config之前,我們可以先憑空想一下一個配置中心需要提供的核心功能有哪些:
- 提供客戶端和服務端的支持
- 提供各個環境的配置
- 配置文件修改後可以快速生效
- 可以提供不同版本的管理
- 可以支持不同的語言(java、.Net、Delphi、node等)
- 支持一定數量的併發
- 高可用(防止意外宕機導致配置不可用)
Spring Cloud Config項目是一個解決分散式系統的配置管理方案。它包含了Client和Server兩個部分,server提供配置文件的存儲、以介面的形式將配置文件的內容提供出去,client通過介面獲取數據、並依據此數據初始化自己的應用。Spring cloud使用git或svn存放配置文件,預設情況下使用git,我們先以git為例做一套示例。
首先在github上面創建了一個文件夾springcloud-config用來存放配置文件,為了模擬生產環境,我們創建以下三個配置文件:
// 開發環境
springcloud-config-dev.properties
// 測試環境
springcloud-config-test.properties
// 生產環境
springcloud-config-pro.properties
每個配置文件中都寫一個屬性springcloud.hello,屬性值分別是 hello dev/test/pro。下麵我們開始配置server端
2. Server端
1. 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>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.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>Greenwich.SR1</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>
2. 配置文件
server:
port: 8080
spring:
application:
name: spring-cloud-config-server
cloud:
config:
server:
git:
uri: https://github.com/meteor1993/SpringCloudLearning # git倉庫的地址
search-paths: chapter6/springcloud-config # git倉庫地址下的相對地址,可以配置多個,用,分割。
username: #Git倉庫用戶名
password: #Git倉庫密碼
Spring Cloud Config也提供本地存儲配置的方式。我們只需要設置屬性spring.profiles.active=native,Config Server會預設從應用的src/main/resource目錄下檢索配置文件。也可以通過spring.cloud.config.server.native.searchLocations=file:E:/properties/屬性來指定配置文件的位置。雖然Spring Cloud Config提供了這樣的功能,但是為了支持更好的管理內容和版本控制的功能,還是推薦使用git的方式。
3. 啟動類 ConfigServerApplication
package com.springcloud.configserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
增加@EnableConfigServer註解,激活對配置中心的支持
4. 測試
首先測試我們的server端能否從github上獲取到我們需要的信息,直接訪問:http://localhost:8080/springcloud-config/pro, 註意: springcloud-config是文件夾的首碼命名,可以看到如下結果:
{
"name":"springcloud-config",
"profiles":[
"pro"
],
"label":null,
"version":"4e3d1a93e869fb336254c480ed1e5b36d58124aa",
"state":null,
"propertySources":[
{
"name":"https://github.com/meteor1993/SpringCloudLearning/chapter6/springcloud-config/springcloud-config-pro.properties",
"source":{
"springcloud.hello":"hello pro"
}
}
]
}
上述的返回的信息包含了配置文件的位置、版本、配置文件的名稱以及配置文件中的具體內容,說明server端已經成功獲取了git倉庫的配置信息。
如果直接查看配置文件中的配置信息可訪問:http://localhost:8080/springcloud-config-dev.properties, 返回:springcloud.hello: hello dev
修改配置文件springcloud-config-dev.properties中配置信息為:springcloud.hello=hello dev update,再次在瀏覽器訪問http://localhost:8080/springcloud-config-dev.properties,返回:springcloud.hello: hello dev update。說明server端會自動讀取自動提交功能。
倉庫中的配置文件會被轉換成web介面,訪問可以參照以下的規則:
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties
以springcloud-config-dev.properties為例,它的application是springcloud-config,profile是dev,label是分支的意思,如果只有一個主分支,可以不寫,預設會訪問master分支,client會根據填寫的參數來選擇讀取對應的配置。
3. client端
主要展示如何在業務項目中去獲取server端的配置信息。
1. 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>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.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>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</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>
2. 配置文件
這裡配置文件分兩個,application.yml和bootstrap.properties
application.yml如下:
server:
port: 8081
spring:
application:
name: spring-cloud-config-client
bootstrap.properties如下:
spring.cloud.config.name=springcloud-config
spring.cloud.config.profile=dev
spring.cloud.config.uri=http://localhost:8080/
spring.cloud.config.label=master
- spring.application.name:對應{application}部分
- spring.cloud.config.profile:對應{profile}部分
- spring.cloud.config.label:對應git的分支。如果配置中心使用的是本地存儲,則該參數無用
- spring.cloud.config.uri:配置中心的具體地址
- spring.cloud.config.discovery.service-id:指定配置中心的service-id,便於擴展為高可用配置集群。
註意:上面這些與spring-cloud相關的屬性必須配置在bootstrap.properties中,config部分內容才能被正確載入。因為config的相關配置會先於application.properties,而bootstrap.properties的載入也是先於application.yml。
3. 啟動類
package com.springcloud.configclient;
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);
}
}
啟動類只需要@SpringBootApplication註解就可以,常規操作。
4. 訪問類
package com.springcloud.configclient.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author: shiyao.wei
* @Date: 2019/7/4 16:19
* @Version: 1.0
* @Desc:
*/
@RestController
public class HelloController {
@Value("${springcloud.hello}")
private String hello;
@RequestMapping("/hello")
public String from() {
return this.hello;
}
}
使用@Value註解來獲取server端參數的值
5. 測試
啟動client端,訪問鏈接:http://localhost:8081/hello, 返回:hello dev update,說明已經正確的從server端獲取到了參數。到此一個完整的服務端提供配置服務,客戶端獲取配置參數的例子就完成了。
可以再進行一個小實驗,我們再次修改springcloud-config-dev.properties中的內容為:hello dev update1,提交至github後,再次訪問http://localhost:8081/hello,可以發現,返回的內容還是hello dev update,這是為什麼呢?因為springboot項目只有在啟動的時候才會獲取配置文件的值,修改github信息後,client端並沒有在次去獲取,所以導致這個問題。如何去解決這個問題呢?留到下一篇我們在介紹。
參考:http://www.ityouknow.com/springcloud/2017/05/22/springcloud-config-git.html