SpringCloud Config是一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端和客户端这两个部分。(建议使用properties格式的配置文件)

服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密/解密信息等访问接口。

客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

SpringCloud Config实现了对服务端和客户端中环境变量和属性配置的抽象映射,因此它除了适用于Spring构建的应用程序,而且还可以在其他任何语言运行的应用程序中使用。

SpringCloud Config实现的配置中心默认采用Git来存储配置信息,所以使用SpringCloud Config构建的配置服务器,天然就支持对微服务应用配置信息的版本管理,而且可以通过Git客户端工具来方便地管理和访问配置内容。当然它也提供了对其他存储方式的支持,如SVN仓库,本地化文件系统。

快速入门

接下来将演示如何构建一个基于Git存储的分布式配置中心,同时详细介绍配置的规则,并在客户端中演示如何通过配置指定微服务应用的所属配置中心,并让其能够从配置中心获取配置信息并绑定到代码中的整个过程。

构建配置中心

为了和其他部分解耦和体现微服务的思想,这里选择新建一个Spring Boot工程,名称为config-server,添加相关依赖。

第一步,在Gitte上新建一个分支,名称为config-server,并将其pull到本地;

第二步,新建一个普通的SpringBoot工程,名称为config-server,注意使用默认的依赖。

第三步,添加项目依赖。Spring Boot工程创建完成后,修改pom.xml文件,添加如下依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR7</spring-cloud.version>
</properties>

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

当然了也可以采用可视化的方式来创建该项目,创建过程如下所示:

第四步,在config-server项目入口类上添加启动注解。接下来在项目的入口类上添加@EnableConfigServer注解,用于开启Spring Cloud Config的服务端功能,如下所示:

1
2
3
4
5
6
7
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}

第五步,属性配置。在config-server项目的application.properties配置文件中添加配置服务的基本信息以及Git仓库的相关信息,笔者这里以Github为例(也可以使用码云),相应的信息如下所示:

1
2
3
4
5
6
7
8
9
10
11
# 配置项目名称
spring.application.name=config-server

# Git仓库地址、仓库下的子目录、用户名、密码
spring.cloud.config.server.git.uri=https://github.com/licheetools/springcloud_test.git
spring.cloud.config.server.git.search-paths=config-repo
spring.cloud.config.server.git.username=licheetools
spring.cloud.config.server.git.password=password

# 配置端口号
server.port=4001

这样一个通过Spring Cloud Config实现,并使用Git管理配置内容的分布式配置中心就完成了。接下来先将该应用启动起来,确保没有错误产生后,才进入后面的学习。

配置规则详解

为了验证上面完成的分布式配置中心config-server是可用的,可以在本地创建一个名为config-repo的目录,然后根据不同环境创建4个不同的配置文件,相应的代码如下:

1
2
3
4
5
6
7
8
9
10
11
# envy.properties文件
envythink=default-1.0

# envy-dev.properties文件
envythink=dev-1.0

# envy-test.properties文件
envythink=test-1.0

# envy-prod.properties文件
envythink=prod-1.0

然后进入到config-repo目录的上一级目录,然后依次执行如下命令:

1
2
3
4
5
git init
git add .
git commit -m "add repo"
git remote add origin https://github.com/licheetools/springcloud_test.git
git push -u origin master

经过上述操作,我们的config-repo目录就已经成功上传到Github上,可以查看确认一下:

同时为了测试版本控制,我们在该Git仓库下新建一个envy分支,并将之前master分支下的4个文件复制过去,并在各个文件中加上branch=book这行代码,之后点击保存即可。

完成上述准备工作后,请确保此时config-server项目依旧处于运行状态,然后我们就可以通过浏览器、POSTman等工具来访问我们的配置内容,访问配置信息的URL与配置文件的映射关系如下所示:

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

请注意上面的application是配置文件的名称,即{application}-{prod|test|dev}.{yml|properties},也就是此处的envy;profile表示环境,上面我们提供了dev、test、prod和默认这四种环境;label表示分支,这里笔者提供了master和book这两个分支。

之后运行项目,在浏览器中访问http://localhost:4001/envy/prod/masterhttp://localhost:4001/envy/prod/book这两个链接,结果如下所示:

这样我们就读取到了我们存放于Git仓库的配置文件信息,可以看到它其实是一个JSON对象。该对象中的name表示配置文件名中application那一部分;profiles表示当前访问的环境;label表示Git上的分支;version是我们往Github上提交信息时产生的版本号。

同时我们还可以看到config-server项目的控制台中还输出了下面的信息:

也就是说配置服务器在从Git中获取到配置信息后,会存储一份在config-server的文件系统中,其实就是通过git clone命令将配置内容复制了一份在本地进行存储,然后读取这些内容并返回给微服务应用进行加载。这样设计的好处就是可以防止当Git仓库出现故障而引起无法加载配置信息的情况发生,开发者可以通过断开网络,然后再一次访问http://localhost:4001/envy/prod/master链接,可以看到在控制台中输出如下信息:

从该图可以看出config-server项目提示无法从远程获取该分支内容进而报错,但是它依然会为该请求返回配置内容,而这些内容就是之前访问Git仓库时存在于config-server项目本地文件系统中的配置内容。

客户端配置映射

通过上述操作,就验证了我们的配置服务中心已经能够正常运作,那么接下来就是尝试如何在微服务应用中获取上述配置信息。

为了和其他部分解耦和体现微服务的思想,这里选择新建一个Spring Boot工程,名称为config-client,添加相关依赖。

第一步,在Gitte上新建一个分支,名称为config-client,并将其pull到本地;

第二步,新建一个普通的SpringBoot工程,名称为config-client,注意使用默认的依赖。

第三步,添加项目依赖。Spring Boot工程创建完成后,修改pom.xml文件,添加如下依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR7</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>
</dependencies>

当然了也可以采用可视化的方式来创建该项目,创建过程如下所示:

请注意IDEA在此时已经没有2.3.3版本,因此需要手动在pom.xml配置文件中将2.3.4修改为2.3.3以确保版本和之前保持一致。

第四步,属性配置。在application.properties配置文件同级目录下新建一个bootstrap.properties文件(注意名字不能修改),然后在里面用于配置一些信息,用于获取配置文件config-server的位置:

1
2
3
4
5
6
spring.application.name=envy
spring.cloud.config.profile=prod
spring.cloud.config.label=envy
spring.cloud.config.uri=http://localhost:4001/

server.port=4002

上述配置参数与Git中存储的配置文件中各个部分的对应关系如下所示:

  • spring.application.name对应于配置文件规则中的{ application }部分;
  • spring.cloud.config.profile对应于配置文件规则中的{ profile }部分;
  • spring.cloud.config.label对应于配置文件规则中的{ label }部分;
  • spring.cloud.config.uri对应于配置中心config-server的地址。

这里需要格外注意的是,上面的属性必须配置在bootstrap.properties文件中,这样config-server中的配置信息才能被正确加载。

在前面我们详细说明了SpringBoot中对于配置文件的加载顺序,对于本应用jar包之外的配置文件加载会优先于应用jar包内的配置内容,而通过使用bootstrap.propertiesconfig-server的配置,使得该应用会从config-server中获取一些外部配置信息,这些信息的优先级比本地的内容要高,从而实现了外部化配置。

回到config-client项目中,接下来我们需要提供一个RESTful风格的API来返回配置中心的envythink属性信息,也就是前面我们在4个properties配置文件中添加的信息。

首先在config-client项目目录下新建一个controller包,并在里面新建一个HelloController类,其中的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RestController
@RefreshScope
public class HelloController {
@Value("${envythink}")
String envythink;

@Autowired
Environment environment;

@GetMapping(value = "/envythinkOne")
public String envythinkOne(){
return this.envythink;
}

@GetMapping(value = "/envythinkTwo")
public String envythinkTwo(){
return environment.getProperty("envythink","未定义");
}
}

关于上述代码,这里有几点需要引起注意:(1)先定义envythink这个属性,然后通过@Value注解来绑定配置服务中配置的envythink属性;(2)除了通过使用@Value注解来对属性进行绑定注入外,还可以使用Environment对象来获取配置属性,需要注意的是这个Environment对象存在于org.springframework.core.env.Environment包内,导包不能出错;(3) 其中的@RefreshScope注解用于实现配置和实例的刷新。

之后启动config-cleint应用,并在浏览器地址栏中访问http://localhost:4002/envythinkOne,我们就可以根据配置内容输出对应环境的envythink信息:

当然了,开发者可以通过修改bootstrap.properties配置文件中的内容来获取不同配置信息进而熟悉配置服务中的配置规则。

如果在上述过程中出现下面的错误,可以点击 这里来寻找解决办法:

这样关于分布式配置中心:SpringCloud Config的基础使用就学习到这里,后续开始学习服务端和客户端的相关配置详情。