天天看點

Spring Cloud微服務架構:分布式配置中心

Spring Cloud Config是Spring Cloud團隊建立的一個全新項目,用來為分布式系統中的基礎設施和微服務應用提供集中化的外部配置支援,它分為服務端與用戶端兩個部分。其中服務端也稱為分布式配置中心,它是一個獨立的微服務應用,用來連接配接配置倉庫并為用戶端提供擷取配置資訊、加密/解密資訊等通路接口;而用戶端則是微服務架構中的各個微服務應用或基礎設施,它們通過指定的配置中心來管理應用資源與業務相關的配置内容,并在啟動的時候從配置中心擷取和加載配置資訊。Spring Cloud Config實作了對服務端和用戶端中環境變量和屬性配置的抽象映射,是以它除了适用于Spring建構的應用程式之外,也可以在任何其他語言運作的應用程式中使用。由于Spring Cloud Config實作的配置中心預設采用Git來存儲配置資訊,是以使用Spring Cloud Config建構的配置伺服器,天然就支援對微服務應用配置資訊的版本管理,并且可以通過Git用戶端工具來友善的管理和通路配置内容。當然它也提供了對其他存儲方式的支援,比如:SVN倉庫、本地化檔案系統。

在本文中,我們将學習如何建構一個基于Git存儲的分布式配置中心,并對用戶端進行改造,并讓其能夠從配置中心擷取配置資訊并綁定到代碼中的整個過程。

準備配置倉庫

  • 準備一個git倉庫,可以在碼雲或Github上建立都可以。比如本文準備的倉庫示例:http://git.oschina.net/didispace/config-repo-demo
  • 假設我們讀取配置中心的應用名為

    config-client

    ,那麼我們可以在git倉庫中該項目的預設配置檔案

    config-client.yml

info:
  profile: default
           
  • 為了示範加載不同環境的配置,我們可以在git倉庫中再建立一個針對dev環境的配置檔案

    config-client-dev.yml

    : 
info:
  profile: dev
           

建構配置中心

通過Spring Cloud Config來建構一個分布式配置中心非常簡單,隻需要三步:

  • 建立一個基礎的Spring Boot工程,命名為:

    config-server-git

    ,并在

    pom.xml

    中引入下面的依賴(省略了parent和dependencyManagement部分):
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.3.5.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>

	<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-config-server</artifactId>
	</dependency>

</dependencies>

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>Brixton.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>
           
  • 建立Spring Boot的程式主類,并添加

    @EnableConfigServer

    注解,開啟Spring Cloud Config的服務端功能。 
@EnableConfigServer
@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		new SpringApplicationBuilder(Application.class).web(true).run(args);
	}

}
           
  • application.properties

    中配置服務資訊以及git資訊,例如: 
spring.application.name=config-server
server.port=7001

# git管理配置
spring.cloud.config.server.git.uri=http://git.oschina.net/didispace/SpringBoot-Learning/
spring.cloud.config.server.git.searchPaths=Chapter9-1-4/config-repo
spring.cloud.config.server.git.username=username
spring.cloud.config.server.git.password=password
           
  • spring.cloud.config.server.git.uri:配置git倉庫位置
  • spring.cloud.config.server.git.searchPaths:配置倉庫路徑下的相對搜尋位置,可以配置多個
  • spring.cloud.config.server.git.username:通路git倉庫的使用者名
  • spring.cloud.config.server.git.password:通路git倉庫的使用者密碼

到這裡,使用一個通過Spring Cloud Config實作,并使用git管理内容的配置中心已經完成了,啟動該應用,成功後開始下面的内容。

Spring Cloud Config也提供本地存儲配置的方式。我們隻需要設定屬性

spring.profiles.active=native

,Config Server會預設從應用的

src/main/resource

目錄下檢索配置檔案。也可以通過

spring.cloud.config.server.native.searchLocations=file:F:/properties/

屬性來指定配置檔案的位置。雖然Spring Cloud Config提供了這樣的功能,但是為了支援更好的管理内容和版本控制的功能,還是推薦使用git的方式。

服務端驗證

為了驗證上面完成的配置伺服器,在http://git.oschina.net/didispace/SpringBoot-Learning/Chapter9-1-4/ 下建立了一個config-repo目錄作為配置倉庫,并根據不同環境建立了下面四個配置檔案:

  • didispace.properties
  • didispace-dev.properties
  • didispace-test.properties
  • didispace-prod.properties

其中設定了一個from屬性,為每個配置檔案分别設定了不同的值,如:

  • from=git-default-1.0
  • from=git-dev-1.0
  • from=git-test-1.0
  • from=git-prod-1.0

為了測試版本控制,在master中,我們都加入1.0的字尾,同時建立一個config-label-test分支,并将各配置檔案中的值用2.0作為字尾。

完成了這些準備工作之後,我們就可以通過浏覽器或POSTMAN等工具直接來通路到我們的配置内容了。

URL與配置檔案的映射關系如下:

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

上面的url會映射

{application}-{profile}.properties

對應的配置檔案,

{label}

對應git上不同的分支,預設為master。

我們可以嘗試構造不同的url來通路不同的配置内容,比如:要通路config-label-test分支,didispace應用的prod環境,可以通過這個url:http://localhost:7001/didispace/prod/config-label-test

{
  "name": "didispace",
  "profiles": [
    "prod"
  ],
  "label": "config-label-test",
  "version": "19de8a25575a7054a34230f74a22aa7f5575a9d1",
  "propertySources": [
    {
      "name": "http://git.oschina.net/didispace/SpringBoot-Learning/Chapter9-1-4/config-repo/didispace-prod.properties",
      "source": {
        "from": "git-prod-2.0"
      }
    },
    {
      "name": "http://git.oschina.net/didispace/SpringBoot-Learning/Chapter9-1-4/config-repo/didispace.properties",
      "source": {
        "from": "git-default-2.0"
      }
    }
  ]
}
           

微服務端映射配置

在完成并驗證了配置服務中心之後,下面看看我們如何在微服務應用中擷取配置資訊。

  • 建立一個Spring Boot應用,在pom.xml中引入spring-cloud-starter-config依賴,完整依賴關系如下:
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.3.5.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>

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

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

</dependencies>

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>Brixton.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>
           
  • 建立最基本的Spring Boot啟動主類 
@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		new SpringApplicationBuilder(Application.class).web(true).run(args);
	}

}
           
  • 建立

    bootstrap.properties

    配置,來指定config server,例如: 
spring.application.name=didispace
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:7001/

server.port=7002
           
  • spring.application.name:對應前配置檔案中的{application}部分
  • spring.cloud.config.profile:對應前配置檔案中的{profile}部分
  • spring.cloud.config.label:對應前配置檔案的git分支
  • spring.cloud.config.uri:配置中心的位址

這裡需要格外注意:上面這些屬性必須配置在

bootstrap.properties

中,config部分内容才能被正确加載。因為config的相關配置會先于

application.properties

,而

bootstrap.properties

的加載也是先于

application.properties

  • 建立一個Rest Api來傳回配置中心的from屬性,具體如下:
@RefreshScope
@RestController
class TestController {

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

    @RequestMapping("/from")
    public String from() {

        return this.from;
    }

}
           

通過

@Value("${from}")

綁定配置服務中配置的from屬性。

啟動該應用,并通路:http://localhost:7002/from ,我們就可以根據配置内容輸出對應環境的from内容了。

繼續閱讀