使用Config Server,您可以在所有環境中管理應用程序的外部屬性。客戶端和服務器上的概念映射與Spring Environment
和PropertySource
抽象相同,因此它們與Spring應用程序非常契合,但可以與任何以任何語言運行的應用程序一起使用。隨着應用程序通過從開發人員到測試和生產的部署流程,您可以管理這些環境之間的配置,並確定應用程序具有遷移時需要運行的一切。服務器存儲后端的默認實現使用git,因此它輕松支持標簽版本的配置環境,以及可以訪問用於管理內容的各種工具。很容易添加替代實現,並使用Spring配置將其插入
以上是Spring Cloud官網對配置服務的描述, 簡單闡述一下我的理解。比如我們要搭建一個網站,需要配置數據庫連接,指定數據庫服務器的IP地址,數據庫名稱,用戶名和口令等信息。通常的方法, 我們可以在一個配置文件中定義這些信息,或者開發一個頁面專門配置這些東西。只有一個web服務器的時候, 很方便。
但假如需要搭建同多台服務器時,當然可以每台服務器做同樣配置,但維護和同步會很麻煩。我理解的配置服務至少有兩種不同場景:
1). 多個客戶使用同一配置: 比如,多台服務器組成的集群,假如后端使用同一數據庫,那么每台服務器都是用相同的配置。
2). 不同客戶使用不同的配置: 比如典型的場景是,開發,測試,生產使用相同的系統,但使用不同的數據庫
如果有個統一的根本配置,是不是就很方便,一個可行的辦法是,把這些配置文件放到一個共享存儲(比如網絡共享盤)中。這樣只需要在共享存儲修改一個或多個配置文件就可以了。但共享文件的方式受到具體布署環境的限制,很多時候很難達到多台Web服務器共享同一個存儲硬盤。
共享盤的缺點是資源定位比較困難,Spring Cloud的解決方案是, 將這些配置文件放到版本管理服務器里面,Spring Cloud缺省配置使用GIT中。所有Web服務均從GIT中獲取這些配置文件。由於GIT服務器與具體Web服務器之間不需要共享存儲, 只要網絡可達就行,從而可以實現Web服務於配置信息的存放位置的解耦。
Spring Cloud統一控制應用和GIT服務的交互,應用只需要按照Spring Cloud的規范配置GIT的URL即可。 使用GIT后,場景2和場景1的區別僅僅是,場景2中不同的client使用不同版本的配置文件,但應用但訪問的文件看起來是會是同一個。Spring Cloud的配置服務結構入下圖
下面我們繼續上一節的例子Spring Cloud 入門之一. 服務注冊 繼續展開, 讓“Hello World”從配置文件helloworld.properties讀出,內容格式如下
hello=Hello World
其中關鍵字hello的值“Hello World”,就是我們要輸出的內容。
一. 創建config Server
1. 創建Config Server, maven工程里面配置spring-cloud-config-server
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
完整配置如下:

1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <groupId>com.chry</groupId> 6 <artifactId>springcloud.helloworld.config.server</artifactId> 7 <version>0.0.1-SNAPSHOT</version> 8 <packaging>jar</packaging> 9 <name>helloworld.config.server</name> 10 <description>Demo Config Server</description> 11 12 <parent> 13 <groupId>org.springframework.boot</groupId> 14 <artifactId>spring-boot-starter-parent</artifactId> 15 <version>1.5.3.RELEASE</version> 16 <relativePath/> <!-- lookup parent from repository --> 17 </parent> 18 19 <properties> 20 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 21 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 22 <java.version>1.8</java.version> 23 </properties> 24 25 <dependencies> 26 <!--eureka server --> 27 <dependency> 28 <groupId>org.springframework.cloud</groupId> 29 <artifactId>spring-cloud-starter-eureka</artifactId> 30 </dependency> 31 <dependency> 32 <groupId>org.springframework.cloud</groupId> 33 <artifactId>spring-cloud-starter-eureka-server</artifactId> 34 </dependency> 35 <dependency> 36 <groupId>org.springframework.cloud</groupId> 37 <artifactId>spring-cloud-config-server</artifactId> 38 </dependency> 39 <!-- spring boot test--> 40 <dependency> 41 <groupId>org.springframework.boot</groupId> 42 <artifactId>spring-boot-starter-test</artifactId> 43 <scope>test</scope> 44 </dependency> 45 </dependencies> 46 47 <dependencyManagement> 48 <dependencies> 49 <dependency> 50 <groupId>org.springframework.cloud</groupId> 51 <artifactId>spring-cloud-dependencies</artifactId> 52 <version>Dalston.RC1</version> 53 <type>pom</type> 54 <scope>import</scope> 55 </dependency> 56 </dependencies> 57 </dependencyManagement> 58 59 <build> 60 <plugins> 61 <plugin> 62 <groupId>org.springframework.boot</groupId> 63 <artifactId>spring-boot-maven-plugin</artifactId> 64 </plugin> 65 </plugins> 66 </build> 67 68 <repositories> 69 <repository> 70 <id>spring-milestones</id> 71 <name>Spring Milestones</name> 72 <url>https://repo.spring.io/milestone</url> 73 <snapshots> 74 <enabled>false</enabled> 75 </snapshots> 76 </repository> 77 </repositories> 78 79 </project>
2. 創建Config Server,它也是一個Spring Boot應用,@EnableConfigServer注解說明了一個Config Server。同樣我們使用@EnableEurekaClient將它注冊到服務中心。
1 package springcloud.helloworld.config.server; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.config.server.EnableConfigServer; 6 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 7 8 @EnableEurekaServer 9 @EnableConfigServer 10 @SpringBootApplication 11 public class ConfigServerApplication { 12 public static void main(String[] args) { 13 SpringApplication.run(ConfigServerApplication.class, args); 14 } 15 }
3. Config server的配置文件appication.yml , 注意配置文件的url是GIT服務器的倉庫地址, searchPaths配置文件所在的文件夾在倉庫中的路徑, 在server端不需要指定具體配置文件名, 因為具體的配置文件是什么有應用(也就是client)決定。
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://git.oschina.net/chrywhy/test
searchPaths: spring-cloud/helloworldConfig
application:
name: config-server
4. 啟動config server后,訪問http://localhost:8888/abc/xyz, 可見如下響應。這個是輸出是並沒有包括具體配置文件的內容, 這個響應說明,config server可以正常訪問我們配置在application.yml中的GIT服務
這個URL是啥意思, 需要解釋一下。我們從輸出就可以看到 abc 就是application的名字,xyz是profile的名字, 注意這里的abc, xyz均是隨便輸入的名字, 並不需要真實存在,config server這個REST接口返回的只是應用名為abc, profile名為xyz時,GIT配置環境的結構。
config server提供的REST接口,Spring Cloud官方文檔提供了幾個可選URL可以是如下幾個:
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties
比如 第三個格式,如果我們在GIT版本庫中有一個配置文件 spring-cloud/helloworldConfig/config-client-dev.properties. 那么訪問http://localhost:8888/config-client-dev.properties就可以顯示配置文件內容。這個例子中, application的名字是"config-client"(也是下面我們即將創建的client), profile名字是dev, 文件后綴是.properties
本例由於配置了eureka服務中心,所以這個config server作為一個eureka client注冊到了 eureka server中, 可以從http://localhost:8761看到我們啟動的config server, 如果不需要注冊到服務中心, 也可把這個配置去掉
二. 創建config client
1. 創建maven工程, pom.xml如下:

1 <?xml version="1.0" encoding="UTF-8"?> 2 <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"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.chry</groupId> 5 <artifactId>Springcloud.helloworld.config.client</artifactId> 6 <version>0.0.1-SNAPSHOT</version> 7 <name>Springcloud.helloworld.config.client</name> 8 <packaging>jar</packaging> 9 <description>Demo Spring Config Client</description> 10 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>1.5.3.RELEASE</version> 15 <relativePath/> <!-- lookup parent from repository --> 16 </parent> 17 18 <properties> 19 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 20 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 21 <java.version>1.8</java.version> 22 </properties> 23 24 <dependencies> 25 <dependency> 26 <groupId>org.springframework.cloud</groupId> 27 <artifactId>spring-cloud-starter-eureka</artifactId> 28 </dependency> 29 <dependency> 30 <groupId>org.springframework.boot</groupId> 31 <artifactId>spring-boot-starter-web</artifactId> 32 </dependency> 33 <dependency> 34 <groupId>org.springframework.cloud</groupId> 35 <artifactId>spring-cloud-starter-config</artifactId> 36 </dependency> 37 <dependency> 38 <groupId>org.springframework.boot</groupId> 39 <artifactId>spring-boot-starter-test</artifactId> 40 <scope>test</scope> 41 </dependency> 42 </dependencies> 43 44 <dependencyManagement> 45 <dependencies> 46 <dependency> 47 <groupId>org.springframework.cloud</groupId> 48 <artifactId>spring-cloud-dependencies</artifactId> 49 <version>Dalston.RC1</version> 50 <type>pom</type> 51 <scope>import</scope> 52 </dependency> 53 </dependencies> 54 </dependencyManagement> 55 56 <build> 57 <plugins> 58 <plugin> 59 <groupId>org.springframework.boot</groupId> 60 <artifactId>spring-boot-maven-plugin</artifactId> 61 </plugin> 62 </plugins> 63 </build> 64 65 <repositories> 66 <repository> 67 <id>spring-milestones</id> 68 <name>Spring Milestones</name> 69 <url>https://repo.spring.io/milestone</url> 70 <snapshots> 71 <enabled>false</enabled> 72 </snapshots> 73 </repository> 74 </repositories> 75 76 77 </project>
2. 創建一個spring boot應用作為client
1 package springcloud.helloworld.config.client; 2 3 import org.springframework.beans.factory.annotation.Value; 4 import org.springframework.boot.SpringApplication; 5 import org.springframework.boot.autoconfigure.SpringBootApplication; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RestController; 8 9 @SpringBootApplication 10 @RestController 11 public class ConfigClientApplication { 12 13 public static void main(String[] args) { 14 SpringApplication.run(ConfigClientApplication.class, args); 15 } 16 17 @Value("${hello}") 18 String hello; 19 @RequestMapping(value = "/hello") 20 public String hello(){ 21 return hello; 22 } 23 }
這個應用非常簡單,就是從Config Server中獲取配置項hello的值,Client Server向Config Server提交REST請求后,Config Server將訪問GIT服務器,並將取得的配置項hello的值返回給client.
3. Config client需要一個應用配置文件, 定義config Server的URL,以及要訪問的GIT具體分支。這個配置文件是bootstrap.yml (或者bootstrap.properties)
1 spring: 2 application: 3 name: config-client 4 cloud: 5 config: 6 label: master 7 profile: dev 8 uri: http://localhost:8888/ 9 server: 10 port: 8881
這個配置定義了應用的名字是config-client(這就是將要用於組裝前面Config Server一節中題到的application), profile采用dev, GIT分支用master。url是config server的地址。那么問題來了,我們似乎沒定義配置文件名, 那配置文件名是什么呢? 這點又體現了約定優於配置的思路, 這里Spring Cloud約定, 應用的配置文件名以如下方式組成:{application}-{profile}.properties(或者{application}-{profile}.yml)。比如我們這個應用的配置文件就是config-client-dev.properties. 所以只需要在GIT的中創建配置文件spring-cloud/helloworldConfig/config-client-dev.properties就可以了, 內容如下:
hello=Hello World from GIT
4. 啟動config-client應用后, 可以訪問http://locahost/8881/hello, 可以看到,應用本身並沒有直接配置hello的具體內容, 也沒指定具體配置文件,所欲這些都由spring cloud框架提交給config server了。

5. 配置的更新
至此,spring cloud的配置管理簡單示例已經完成,但client 不能自動感知服務端的變化。 比如,我們修改了GIT中的文件內容,但無論如何刷新client端的頁面,都不能反映配置的變化。下一節介紹Spring Cloud的配置自動更新機制