Spring Cloud Config統一的配置中心同注冊中心Eureka一樣,也分服務端和客戶端。服務端用來保存配置信息,客戶端用來讀取。它的優勢是基於Git倉庫,支持多環境、多分支配置、動態刷新。我們把服務網關Zuul(參見Greenwich.SR2版本的Spring Cloud Zuul實例)看成Config的客戶端,它的路由配置(zuul.routes開頭配置項)我們從Git上配置,如此一來我們直接修改本地Git上的路由配置再push到遠程倉庫后,調用/bus/refresh即可生效,達到動態路由的目的。同理,其他微服務組件也可以作為Config客戶端讀取業務配置。
至於如何實現配置信息支持動態更新,那就需要另外一個組件的出手了:Spring Cloud BUS,消息總線。原理是Git上配置更新后,通過調用/bus/refresh接口,基於消息中間件推送給所有Config客戶端。這里的消息中間件用Kafka。Config服務端也支持集群,為了讓Config客戶端調用Config服務端集群方便,我們集成Eureka來發現Config服務端。
先看Config服務端,三板斧:
1、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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>configuration-service</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-kafka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-kafka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-bus</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR2</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:
#本機端口 server.port=8766 #本機服務名 spring.application.name=config-server #注冊中心地址 eureka.client.service-url.defaultZone=http://localhost:8888/eureka/ #Git倉庫地址 spring.cloud.config.server.git.uri=https://github.com/wuxun1997/spring-cloud-demo #Git倉庫路徑下搜索路徑 spring.cloud.config.server.git.search-paths=config #支持動態刷新 spring.cloud.bus.refresh.enabled=true management.endpoints.web.exposure.include=bus-refresh #配置BUS使用的消息中間件Kafka spring.kafka.bootstrap-servers=127.0.0.1:9092
3、主類通過@EnableConfigServer啟動配置中心:
package hello; 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 ConfigServiceApplication { public static void main(String[] args) { SpringApplication.run(ConfigServiceApplication.class, args); } }
啟動Config服務端前需要啟動本地Kafka,否則它會一直提示連接失敗。如果連不上你的git倉庫,在application.properties中加上用戶名、密碼配置:
#Git倉庫用戶、密碼 spring.cloud.config.server.git.username=你的Git倉庫用戶名XXX spring.cloud.config.server.git.password=你的Git倉庫密碼XXX
現在我們在git倉庫創建兩個配置文件:
hello.properties:

config/configclient-test.properties:

我們可以直接對Config服務端請求:

接着我們新建項目來看看Config客戶端。再來三板斧:
1、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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>configuration-client</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-kafka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-kafka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-bus</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR2</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、bootstrap:
#本機端口 server.port=8778 #本機服務名 spring.application.name=configClient #注冊中心地址 eureka.client.service-url.defaultZone=http://localhost:8888/eureka/ #支持注冊中心訪問Config服務端 spring.cloud.config.discovery.enabled=true #Config服務端服務名 spring.cloud.config.discovery.service-id=config-server #git倉庫配置文件分支(默認即為master) spring.cloud.config.label=master #git倉庫配置文件環境信息 spring.cloud.config.profile=test
3、主類通過@RefreshScope支持動態獲取Config最新配置:
package hello; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @EnableDiscoveryClient @SpringBootApplication public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } } @RefreshScope @RestController class MessageRestController { @Value("${message:Hello default}") private String message; @RequestMapping("/message") String getMessage() { return this.message; } }
現在我們先通過Config客戶端獲取到Git倉庫的master分支下config目錄下的configClient(默認拿Config客戶端的服務名作為properties文件名)-test(環境)的配置項:

接下來我們動態刷新,直接去Git倉庫上編輯message的值好了:

提交后我們直接看Config服務端,也自動更新了:

但是這是客戶端並未更新,需要我們調用/bus-refresh接口去刷新一下服務端:

這會兒再調用客戶端就能獲取最新配置了:

