在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config 配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git以及Subversion。支持远程更改,服务在不重启的情况下,使配置生效。
spring cloud config分server和client端。
org.springframework.cloud
spring-cloud-config-server
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class SpringcloudConfigApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudConfigApplication.class, args);
}
}
spring:
application:
name: config
cloud:
config:
server:
git:
uri: 远程仓库地址
username: 远程仓库账号用户名
password: 远程仓库账号密码
client:
service-url:
defaultZone: http://localhost:8761/eureka/
register-with-eureka: false
instance:
prefer-ip-address: true
server:
#自我保护模式,测试环境关闭,生产环境一定要打开
enable-self-preservation: false
先看一下我的git仓库的内容:
启动,访问。访问方式:/{label}/{name}-{profile}.想要展示的文件类型
访问成功,我们也可以指定json格式返回。
此时,查看控制台日志,发现本地会创建Git仓库。
由于我们生产环境一般是linux,文件夹一般指定了访问权限,为避免默认缓存的文件位置没有写的权限,需要指定一下config-repo的位置。
git:
basedir: I:/Code/EclipseEEWorkspace/springcloud-config/config-repo-cache
重启,观察控制台,配置生效了:
org.springframework.cloud
spring-cloud-config-client
bootstrap.yml:
spring:
application:
name: product
cloud:
config:
discovery:
enabled: true
service-id: CONFIG
profile: dev
server:
port: 8081
@RestController
@RequestMapping("/env")
public class ServerController {
@Value("${env}")
private String env;
@GetMapping("/print")
public String print() {
return env;
}
}
访问接口,成功获取的配置。
此时,在远程Git仓库修改该配置env => prod,访问发现env打印的依赖时dev,修改未生效。但我们访问config-server,却是生效的。
接下来是重点,必须怀疑,此时config-server获取的最新配置,但没有及时通知到service刷新,所以需要引入 Spring Cloud Bus自动刷新配置。
原理:当远程仓库的配置文件更新,config-server获取到最新的配置文件,需要通过Mq消息中间件给各Services发生更新消息。SpringCloud为我们提供了一个刷新配置的接口 Bus-Refrsh,我们可以采用git的WebHooks实现动态更新,即当git远程仓库配置文件发生变更时,Git自动刷新Bus-Refrsh接口。
需要修改config的yml文件,将bus-refresh暴露出来。
#需要暴露bus-refresh接口 [/actuator/bus-refresh/{destination}],methods=[POST]
#include: "*" 表示暴露所有 endpoints 出去,默认是“health”,“info”
management:
endpoints:
web:
exposure:
include: "*"
此时,采用手动刷新试试看是否生效:
发现mq有收到消息,控制台出现重新拉取配置的日志
但此时通过get请求获取配置还是未生效,还需要在加@RefreshScope
@RestController
@RequestMapping("/env")
@RefreshScope
public class ServerController {
@Value("${env}")
private String env;
@GetMapping("/print")
public String print() {
return env;
}
}
此时就能做到自动刷新配置了。
但我们总不能每次发生修改了,手动去刷新一次bus-refresh接口,此时我们可以借助git的webhooks。Spring Cloud Config专门提供了用于Webhooks的路由 monitor.
报错,开源中国的git格式不兼容,可以采用github的git试一下,是ok的。