在开发普通的 web 应用中,我们通常是将配置项写在单独的配置文件中,比如application.yml
,application.properties
,但是在微服务架构中,可能会出现数百个微服务,如果每个微服务将配置文件写在自身的配置文件中,会导致配置文件的管理非常复杂。因此集中式的配置管理是非常有必要的,每个服务启动时从集中式的存储库中读取需要的配置信息。其模型如下:
简单来说就是如下几点:
由于本系列为 spring cloud,所以使用Spring Cloud Config
来构建配置管理,当然还有很多其他优秀的解决方案(Etcd,Eureka,Consul...)。
spring cloud 是建立在 spring boot 的基础上的,因此需要有 spring boot 的构建基础。
pom 主要依赖如下(篇幅原因列出主要内容,完整代码请到 github 上查看),spring boot 版本和 spring cloud 版本如下,之后不在赘述:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.4.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<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>Camden.SR5</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</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>
只需在 spring boot 启动类上加入一个@EnableConfigServer
注解即可。
这里是给配置服务使用的配置文件,用于声明端口,存储库类别等信息,并不是给其他微服务使用的配置。配置如下(使用文件存储配置信息):
server:
port: 8888
spring:
profiles:
# 使用文件系统来存储配置信息,需要设置为native
active: native
cloud:
config:
server:
native:
# 使用文件来存放配置文件,为每个应用程序提供用逗号分隔的文件夹列表
searchLocations: file:///D:/configFolder/licensingservice
通过上面的searchLocations
可知目前有一个名为 licensingservice 的应用程序,在对应目录下创建如下三个配置文件:
server:
port: 10010
spring:
application:
name: licensingservice
server:
port: 10011
server:
port: 10012
配置文件命名约定为:应用程序名称-环境名称.yml
。现在启动应用便能通过 http 请求来获取配置了。
请求localhost:8888/licensingservice/default,返回结果如下:
{
"name": "licensingservice",
"profiles": ["default"],
"label": null,
"version": null,
"state": null,
"propertySources": [
{
"name": "file:///D:/configFolder/licensingservice/licensingservice.yml",
"source": {
"server.port": 10001,
"spring.application.name": "licensingservice"
}
}
]
}
请求localhost:8888/licensingservice/dev,返回结果如下:
{
"name": "licensingservice",
"profiles": ["dev"],
"label": null,
"version": null,
"state": null,
"propertySources": [
{
"name": "file:///D:/configFolder/licensingservice/licensingservice-dev.yml",
"source": {
"server.port": 10011
}
},
{
"name": "file:///D:/configFolder/licensingservice/licensingservice.yml",
"source": {
"server.port": 10001,
"spring.application.name": "licensingservice"
}
}
]
}
上面写了如何使用 spring cloud config 构建配置服务,这一节来构建 licensingserivce 服务,使用上面的配置服务来获取配置文件。
创建 springboot 项目 licensingservice,主要依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
共两个配置文件,application.yml
,bootstrap.yml
java -Dsptring.cloud.config.uri=.... -Dspring.profiles.active=prod xxxxx.jar
启动 licensingservice 可以发现启动端口为 10011,说明远程读取配置生效了。
在 github 某个仓库下创建配置文件,比如在https://github.com/FleyX/demo-project仓库下的springcloud/config目录下创建 licengingservice 服务的配置文件。
修改 confsvr 中的 application.yml
server:
port: 8888
spring:
profiles:
# 使用文件系统来存储配置信息,需要设置为native,git设置为git
active: git
application:
name: test
cloud:
config:
server:
native:
# 使用文件来存放配置文件,为每个应用程序提供用逗号分隔的文件夹列表
searchLocations: file:///D:/configFolder/licensingservice
git:
uri: https://github.com/FleyX/demo-project
# 查找配置文件路径(,分隔)
search-paths: springcloud/config/licensingservice
#如果为公开仓库,用户名密码可不填写
username:
password:
#配置git仓库的分支
label: master
重新启动,即可发现配置成功生效。
使用 spring cloud 配置服务器时,有一个问题是如何在属性变化时动态刷新应用程序。spring cloud 配置服务始终提供最新版本的属性,对低层存储库属性的更改将会是最新的。但是 config client 并不会知道配置的变更,因此不会自动刷新属性。
Spring Boot Actuator 提供了一个@RefreshScope
属性来重新读取应用程序配置信息,开发人员可通过/refresh
进行刷新。该注释需要注释在启动入口类上。注意:只会加载自定义 Spring 属性,例如数据库,端口等配置不会重新加载。
本篇只是用到了 spring-cloud-config 这个来进行配置集中管理,并没有涉及到微服务,在下一篇将开始微服务的学习。 本篇两个项目代码存放于:点击跳转