赞
踩
在我们了解spring cloud config之前,我们可以想想一个配置中心提供的核心功能应该有什么?
Spring Cloud Config可以完美的支持以上所有的需求。
Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。Spring cloud使用git或svn存放配置文件,默认情况下使用git.
Config支持配置文件放在远程Git仓库里,当我们进行更改配置的时候,只需要在本地更改,然后推送到Git仓库中就可以了,所有的客户端都可以去配置中心获取配置,当配置文件修改时(本地推送到git),会触发git的webhook回调,最终触发spring cloud bus(消息总线),然后由消息总线通知相关的应用,这样就是实现配置统一管理。
我们进行配置管理,首先需要一个仓库,我在github建立一个中心仓库:配置中心仓库,新建一个文件夹config,我在这个文件夹下建了两个文件
cloud-config-dev.yml
cloud-config-prd.yml
每个文件内容大概是这样的
spring:
profiles:
active: dev / prd
创建config-server-8009模块,添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
添加配置:
server: port: 8009 spring: application: name: config-server cloud: config: server: git: uri: https://github.com/ROAOR1/config-server.git #git上的路径 username: #账号 password: #密码 search-paths: config #要搜索的路径,填我们刚刚创建的文件夹 eureka: client: service-url: defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/
启动类加上@EnableConfigServer,声明是一个配置中心
@EnableEurekaClient
@EnableConfigServer
@SpringBootApplication
public class ConfigServer8009Application {
public static void main(String[] args) {
SpringApplication.run(ConfigServer8009Application.class, args);
}
}
接着我们启动两个注册中心,和当前的config服务,访问的时候只需要在后面加上文件名就可以了
访问http://localhost:8009/cloud-config/prd 可以获取到配置文件的位置、版本、配置文件的名称以及配置文件中的具体内容。
Spring Cloud Config 有它的一套访问规则,我们通过这套规则在浏览器上直接访问就可以。
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
上面的 URL 对应 /{application}/{profile}[/{label}] 这个规则,其中 {label} 对应 Git 上不同的分支,默认为 master。它的 application 是 cloud-config,profile 是 prd。
当我们修改git仓库中的文件,将数据改为prd update,重新访问http://localhost:8009/cloud-config/prd 去获取配置文件,会发现配置中心会自动拉取最新的配置文件
配置中心的高可用很简单,第一步将配置中心注册到注册中心,第二步多个配置中心指向一个git仓库。我们上面已经将配置中心注册到注册中心,只需要建一个一样的配置中心,指向相同的git仓库就可以了。
创建config-server-8010模块
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
添加配置
server: port: 8010 spring: application: name: config-server cloud: config: server: git: uri: https://github.com/ROAOR1/config-server.git #git上的路径 username: #账号 password: #密码 search-paths: config #要搜索的路径,填我们刚刚创建的文件夹 eureka: client: service-url: defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/
启动类
@EnableEurekaClient
@EnableConfigServer
@SpringBootApplication
public class ConfigServer8009Application {
public static void main(String[] args) {
SpringApplication.run(ConfigServer8009Application.class, args);
}
}
接着分别启动两个注册中心,两个配置中心,分别访问http://localhost:8009/cloud-config-dev.yml,http://localhost:8010/cloud-config-dev.yml,可以看到两个配置中心成功加载配置文件
创建两个配置中心客户端config-client-8011,config-client-8012
pom文件
<!--是用来接收更新的消息,类似心跳检测--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
添加配置
application.yml文件
server: port: 8011 spring: application: name: config-client data: ${spring.profiles.active} #用这个来加载配置中心中的数据 ---------------------------------------------------- server: port: 8012 spring: application: name: config-client data: ${spring.profiles.active}
bootstrap.yml文件,两个模块的文件一样
spring:
cloud:
config:
name: cloud-config #对应 {application}
label: master #对应{label}
profile: dev #对应{profile}
discovery:
enabled: true #开启 Config 服务发现支持
service-id: config-server #配置中心Id
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/
注意:上面这些与 Spring Cloud Config 相关的属性必须配置在 bootstrap.yml 中,config 部分内容才能被正确加载。因为 config 的相关配置会先于 application.yml,而 bootstrap.yml 的加载也是先于 application.yml。
启动类
@EnableEurekaClient
@SpringBootApplication
public class ConfigClient8011Application {
public static void main(String[] args) {
SpringApplication.run(ConfigClient8011Application.class, args);
}
}
controller,用来测试
@RestController
public class ConfigController {
@Value("${data}")
private String data;
@RequestMapping("/getData")
public void getData(){
System.out.println(data);
}
}
分别访问http://localhost:8011/getData ,http://localhost:8012/getData,可以看到控制台打印出dev,说明客户端读取配置文件成功。
接着我们修改dev配置文件,改为dev update,重新访问http://localhost:8011/getData ,http://localhost:8012/getData,会发现控制台打印的数据还是dev
因为 Spring Cloud Config 分服务端和客户端,服务端负责将 Git 中存储的配置文件发布成 REST 接口,客户端可以从服务端 REST 接口获取配置。但客户端并不能主动感知到配置的变化,主动去获取新的配置。客户端如何去主动获取新的配置信息呢,Spring Cloud 已经给我们提供了解决方案,每个客户端通过 POST 方法触发各自的 /actuator/refresh。
用的就是我们上面加入的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在bootstrap.yml中加入
management:
endpoints:
web:
exposure:
include: refresh #暴露了refresh接口
在需要读取配置的类上增加 @RefreshScope 注解 ,在客户端执行 /actuator/refresh 的时候就会更新此类下面的变量值。
@RefreshScope
@RestController
public class ConfigController {
@Value("${data}")
private String data;
@RequestMapping("/getData")
public void getData(){
System.out.println(data);
}
}
重启客户端,这个时候客户端读取的肯定是最新的配置文件,我们要把刚刚的配置还原成dev。再进行修改成dev update,接着访问结果还是dev,没有问题。
接着使用postman访问,使用post方法发送请求 http://localhost:8011/actuator/refresh
我们看到这个消息就说明属性更新成功。最后访问接口http://localhost:8011/getData,发现数据成功改变
这就结束了吗,并没有,总不能每次改了配置后,就用 postman 访问一下 refresh 接口吧,还是不够方便呀。 github 提供了一种 webhook 的方式,当有代码变更的时候,会调用我们设置的地址,来实现我们想达到的目的。
Webhook 是当某个事件发生时,通过发送 HTTP POST 请求的方式来通知信息接收方。Webhook 来监测你在 Github.com 上的各种事件,最常见的莫过于 push 事件。如果你设置了一个监测 push 事件的 Webhook,那么每当你的这个项目有了任何提交,这个 Webhook 都会被触发,这时 Github 就会发送一个 HTTP POST 请求到你配置好的地址。
填上回调的地址,也就是上面提到的 actuator/refresh 这个地址,但是必须保证这个地址是可以被 github 访问到的,如果是内网就没办法了。这也仅仅是个演示,一般公司内的项目都会有自己的代码管理工具,例如自建的 gitlab,gitlab 也有 webhook 的功能,这样就可以调用到内网的地址了。
events 事件类型 | 描述 |
---|---|
push | 仓库有 push 时触发。默认事件 |
create | 当有分支或标签被创建时触发 |
delete | 当有分支或标签被删除时触发 |
这样我们就可以利用 webhook 的机制去触发客户端的更新,但是当客户端越来越多的时候,hook 机制也不够优雅了,另外每次增加客户端都需要改动 webhook 也是不现实的。其实,Spring Cloud 给了我们更好解决方案 ——Spring Cloud Bus。后续我们将继续学习如何通过 Spring Cloud Bus 来实现以消息总线的方式进行通知配置信息的变化,完成集群上的自动化更新。
Spring Cloud(七):配置中心(Git 版与动态刷新)【Finchley 版】
项目代码
SpringCloud 汇总【Greenwich 版】
SpringCloud(一):Eureka注册中心【Greenwich 版】
SpringCloud(二):Ribbon负载均衡【Greenwich 版】
SpringCloud(三):Feign声明式服务调用【Greenwich 版】
SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】
SpringCloud(五):Hystrix的请求熔断与服务降级【Greenwich 版】
SpringCloud(六):Hystrix的请求合并【Greenwich 版】
SpringCloud(七):Hystrix仪表盘与Turbine集群监控【Greenwich 版】
SpringCloud(八):Zuul网关【Greenwich 版】
SpringCloud(九):Config配置中心【Greenwich 版】
SpringCloud(十):Bus消息总线【Greenwich 版】
SpringCloud(十一):Stream消息驱动 + RabbitMQ【Greenwich 版】
SpringCloud(十二):Sleuth链路跟踪【Greenwich 版】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。