一.微服务架构遇到的问题
随着项目规模的日益庞大,每个单独的服务器的配置文件随着不断地项目升级内容而不断增多,会引起一系列的更新和重启,运维苦不堪言也容易出错。所以就想到有没有一个办法能够统一管理所有项目的配置文件.
二.解决问题
市面上开源的配置中心有很多,360的QConf、淘宝的diamond、百度的disconf都是解决这类问题。这些开源的软件以及解决方案都很优秀,但是Spring Cloud Config,因为它功能全面而强大,可以无缝的和spring框架体系相结合,够方便够简单颜值高。
三.核心功能
1.提供服务端和客户端支持 :它包含了Client和Server两个部分,server提供配置文件的存储(是存储到本地上,还是存储到git上)、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。
2.集中管理各环境的配置文件 :在一个服务中管理开发环境下的配置,测试环境下的配置和生产环境下的配置。
3.配置文件修改之后,可以快速的生效 :server提供配置文件的存储,如果是存储到本地上,修改配置文件后,必须重启config服务端才生效,如果是存储到git上不需要重启。
4.可以进行版本管理
5.支持大的并发查询
6.支持各种语言
四.配置信息存储到本地上的使用方式
4.1Config服务端配置
- 单独创建项目
- 引入依赖
<dependencies>
<!--将Config服务端注册到eureka上-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--作为Config服务端要依赖的包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
- 配置application.yml
server:
port: 8081
eureka:
client:
serviceUrl:
defaultZone: http://8000/eureka # 将本项目的ip和端口号注册到eureka上
spring:
application:
name: spring-cloud-config-server # 本项目在eureka的标识名
profiles:
active: native # 配置使用本地储存
cloud:
config:
server:
native:
search-locations: classpath:properties # 搜索src/main/resource下的properties文件夹下的文件
- 在properties包下创建开发环境配置neo-config-dev.properties;测试环境配置neo-config-test.properties;生产环境配置neo-config-pro.properties
- 在项目启动类上加:
@EnableConfigServer - 测试一下Config客户端能否正常运作: http://localhost:8081/neo-config/dev
4.2 Config客户端配置
- 哪个服务器需要配置哪个就配置
- 引入依赖
<!--引入config客户端包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
- 在resources下配置bootstrap.properties
spring.cloud.config.name=neo-config
spring.cloud.config.profile=dev
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=spring-cloud-config-server
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
spring.application.name:对应{application}部分
spring.cloud.config.profile:对应{profile}部分
eureka.client.serviceUrl.defaultZone:标注config客户端是注册在这个地址上面
spring.cloud.config.discovery.service-id:就是config服务端在eureka中的标识名
特别注意:上面这些与spring-cloud相关的属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为config的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties。
- 配置application.properties
- 测试
五.配置文件在GIT上的使用方式
在git上配置比在本地上配置避免了当配置文件修改时需要重新启动服务器的缺点。首先在github上面创建了一个文件夹config-repo用来存放配置文件,为了模拟生产环境,我们创建以下三个配置文件:
// 开发环境
neo-config-dev.properties
// 测试环境
neo-config-test.properties
// 生产环境
neo-config-pro.properties
每个配置文件中都写一个属性neo.hello,属性值分别是 hello im dev/test/pro 。下面我们开始配置server端。
5.1server 端
5.1.1、添加依赖
<dependencies>
<!--将Config服务端注册到eureka上-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
5.1.2.在application.yml中配置
server:
port: 8006
eureka:
client:
serviceUrl:
defaultZone: http://8000/eureka # 将本项目的ip和端口号注册到eureka上
spring:
application:
name: spring-cloud-config-server # 本项目在eureka的标识名
cloud:
config:
server:
git:
uri: https://github.com/tianhuia/config-repo.git/ # 配置git仓库的地址
search-paths: config-repo # git仓库地址下的相对地址,可以配置多个,用,分割。
username: # git仓库的账号
password: # git仓库的密码
Spring Cloud Config也提供本地存储配置的方式。我们只需要设置属性spring.profiles.active=native,Config Server会默认从应用的src/main/resource目录下检索配置文件。也可以通过spring.cloud.config.server.native.searchLocations=file:E:/properties/属性来指定配置文件的位置。虽然Spring Cloud Config提供了这样的功能,但是为了支持更好的管理内容和版本控制的功能,还是推荐使用git的方式。
5.1.3.启动类
启动类添加@EnableConfigServer
,激活对配置中心的支持。
@EnableConfigServer
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
到此server端相关配置已经完成
5.1.5.测试服务端是否能读取到github上面的配置信息
首先我们先要测试server端是否可以读取到github上面的配置信息,直接访问:http://localhost:8006/neo-config/dev
返回信息如下
{"name":"neo-config","profiles":["dev"],"label":null,"version":"389ffdb255f823237b5647d89fe0cead5c4ab7f9","state":null,"propertySources":[{"name":"https://github.com/miaohangbo/config-repo//neo-config-dev.properties","source":{"neo.hello":"hello im dev"}}]}
上述的返回的信息包含了配置文件的位置、版本、配置文件的名称以及配置文件中的具体内容,说明server端已经成功获取了git仓库的配置信息。
如果直接查看配置文件中的配置信息可访问:http://localhost:8006/neo-config-dev.properties,返回:neo.hello: hello im dev
修改配置文件neo-config-dev.properties中配置信息为:neo.hello=hello im dev update,再次在浏览器访问http://localhost:8006/neo-config-dev.properties,返回:neo.hello: hello im dev update。说明server端会自动读取最新提交的内容
仓库中的配置文件会被转换成web接口,访问可以参照以下的规则:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
以neo-config-dev.properties为例子,它的application是neo-config,profile是dev。client会根据填写的参数来选择读取对应的配置。
5.2.client 端
主要展示如何在业务项目中去获取server端的配置信息
5.2.1 添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
引入spring-boot-starter-web包方便web测试
5.2.2 配置文件
需要配置两个配置文件,application.properties和bootstrap.properties
application.properties如下:
spring.application.name=spring-cloud-config-client
server.port=8002
bootstrap.properties如下:
spring.cloud.config.name=neo-config
spring.cloud.config.profile=dev
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=spring-cloud-config-server
eureka.client.serviceUrl.defaultZone= http://localhost:8000/eureka/
5.2.3 web测试
使用@Value
注解来获取server端参数的值
@RestController
class HelloController {
@Value("${neo.hello}")
private String hello;
@RequestMapping("/hello")
public String from() {
return this.hello;
}
}
启动项目后访问:http://localhost:8003/hello,返回:hello im dev update说明已经正确的从server端获取到了参数。到此一个完整的服务端提供配置服务,客户端获取配置参数的例子就完成了。
我们在进行一些小实验,手动修改neo-config-dev.properties中配置信息为:neo.hello=hello im dev update1提交到github,再次在浏览器访问http://localhost:8003/hello,返回:neo.hello: hello im dev update,说明获取的信息还是旧的参数,这是为什么呢?因为springboot项目只有在启动的时候才会获取配置文件的值,修改github信息后,client端并没有在次去获取,所以导致这个问题。
六. refresh 刷新
Spring Cloud Config分服务端和客户端,服务端负责将git(svn)中存储的配置文件或者本地的配置文件发布成REST接口,客户端可以从服务端REST接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置。客户端如何去主动获取新的配置信息呢,springcloud已经给我们提供了解决方案,每个客户端通过POST方法触发各自的/refresh
修改客户端项目已到达可以refresh的功能。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
增加了spring-boot-starter-actuator
包,spring-boot-starter-actuator
是一套监控的功能,可以监控程序在运行时状态,其中就包括/refresh
的功能。
6.1、 开启更新机制
需要给加载变量的类上面加载@RefreshScope
,在客户端执行/refresh
的时候就会更新此类下面的变量值。
@RestController
@RefreshScope // 使用该注解的类,会在接到SpringCloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。
class HelloController {
@Value("${neo.hello}")
private String hello;
@RequestMapping("/hello")
public String from() {
return this.hello;
}
}
6.2、测试
Spring boot 2.0的改动较大,/bus/refresh全部整合到actuador里面了,所以之前1.x的management.security.enabled全部失效,不适用于2.0
适用于2.0的配置是这样的(在客户端的application.yml中配置):
management.endpoints.web.exposure.include=refresh
OK 这样就改造完了,以post请求的方式来访问http://localhost:8003/actuator/refresh
就会更新修改后的配置文件。
我们再次来测试,首先访问http://localhost:8003/hello
,返回:hello im dev
,我将库中的值修改为hello im dev update
。在postman中发送post请求http://localhost:8003/actuator/refresh,返回
[“neo.hello”]说明已经更新了
neo.hello的值。我们再次访问
http://localhost:8003/hello,返回:
hello im dev update`,客户端已经得到了最新的值。