随着项目越来越大,模块越来越多,配置文件少则四五个多则二三十个,配置放代码和配置文件里不够安全,放maven里不够优雅,放环境变量里是够安全,随着docker的流行也还算方便,可不能统一管理,况且还要写个脚本往环境变量里写,这都太麻烦了,能不能用一个优雅,安全又方便统一管理的方法来解决这些问题呢,SpringCloudConfig就是一个比较好的解决方案。
用例说明:
- 一个eureka注册中心,提供服务的注册与发现
- 一个远端git仓库,用于存放配置文件
- 一个config-server,提供springCloudConfig服务
- 一个config-client,调用config-server提供的服务
- config-server和config-client都需要集成rabbitMQ,当远端配置文件更改时用于通知
1.配置eureka注册中心
配置注册中心没有什么特别的,这里eureka启动端口为默认的8761,配置文件如下
spring:
application:
name: config-eureka
server:
port: 8761
eureka:
client:
register-with-eureka: false
server:
enable-self-preservation: false
2.建一个git仓库
我这里用开源中国的码云新建了一个私有仓库 config-repo ,在里面新建了几个配置文件
远端仓库
3.配置config-server
maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!--config-server作为一个服务需要注册到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-starter-bus-amqp</artifactId>
</dependency>
配置文件
- 需要说明当config-server启动的时候会把远端git仓库拉取到本地,至于拉到本地哪,在下面的 basedir 配置。
- 远端git可以使用账号密码,也可以配置私钥访问,如下 private-key
- 我这里RabbitMQ起在了本地,账号和密码都是默认的,所以没有配置
#eureka注册中心地址
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
#启动端口
server:
port: 8080
#应用名(server-id)
spring:
application:
name: config-server
#cloud-server配置
cloud:
config:
server:
git:
# git地址
uri: https://gitee.com/zolvces/config-repo.git
# git账号密码
username: ××××××××
password: ××××××××
# 本地仓库
basedir: D:/localGit/
# 也可以使用私钥链接远程仓库
# private-key:
# rabbitMQ配置
# rabbitmq:
# username:
# password:
# host:
# port:
#暴露/actuator/bus-refresh接口(动态刷新配置文件需要)
management:
endpoints:
web:
exposure:
include: bus-refresh
启动类
刚刚已近说过,config-server作为一个服务必须要注册到eureka才能被其他服务发现调用,所以需要 EnableDiscoveryClient
//启用configServer
@EnableConfigServer
//启用eurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
启动config-server
在启动前,请确认配置的RabbitMQ已经启动,启动完成后我们可以按照如下规则访问config-server
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
-
label : git仓库的分支
-
application :配置文件的文件名,如我的残酷里的clientOne.yml 中的“clientOne”,对应服务的应用名,这个后面再说
-
profile:这个很熟悉,配置文件的后缀,可以对应服务启用的环境
访问配置文件
了解了这三个参数的含义,我们就可以通过config-service获取到仓库里的任何配置文件
- 访问master分支的 clientOne.yml
这里会有点纳闷,为什么是clientOne-a.yml,这个-a是怎么来的,注意看上面的访问规则,application 和profile 是必须的,lable默认是master,spring的原本意愿,应该是希望在clientOne.yml里放置的是公告的配置,当访问clientOne-XXX.yml 时,获取到的配置文件是clientOne.yml与clientOne-XX.yml 的“并集”,所以clientOne-a.yml 里面是包含clientOne.yml里的配置的。
- 访问master分支的clientOne-dev.yml
- 访问dev分支的clientOne-test.yml
当然若不是使用yaml格式的配置,使用properties格式的也是一样的
访问clientOne-a4.配置config-client
maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springCloudConfigClient-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--eurekaClient-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--rabbitMQ-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
启动类
config-client 的启动类并不需要什么特别的设置,启用eureka客户端就行
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigClientOneApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientOneApplication.class, args);
}
}
配置文件
需要说明的是再config-client,需要把配置文件由application.yml改为bootstrap.yml,再idea下,文件图标会加上一朵云,代表需要读取远端的配置来引导启动项目。
# cloud-config-client配置
spring:
cloud:
config:
discovery:
# 启用config-client
enabled: true
# config-server的application.name
service-id: config-server
# 默认就是master分支
# label: master
# 还可以在spring.application.name配置
# name: order
# 还可以在spring.profiles.active配置
# profile: test
# 设置为true时若连接不上configServer无法启动项目
# fail-fast: true
application:
name: clientOne
profiles:
active: dev
# eureka注册中心地址,这是必须的,因为我们首先需要从注册中心拿到config-server的服务
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
同样,由于我使用了本地rabbitMQ的默认用户名密码,所以没有配置RabbitMQ,其次,主要配置就是lable,name,profile这三个参数,上面已经说的很清楚了,在这里可以看到我甚至都没有配置server.port,没有错,我们甚至可以把启动端口都配置在远端。
配置刷新范围
由于需要动态改变配置文件里的参数,所以要告诉spring需要刷新哪些参数,这里用到一个注解 @RefreshScope 它可以打在类上或是方法上,指明刷新的范围,如下会动态刷新message参数的配置。
@RestController
@RefreshScope
public class TestController {
@Value("${message}")
private String message;
@GetMapping("/getMessage")
public String getMessage(){
return this.message;
}
}
5.何时刷新
在更改了远端git仓库上的配置时,访问config-serve 的/{application}/{profile}[/{label}]
发现返回的配置是修改过后的,但是访问config-client的getMessage发现并没有什么变化,这时若重启config-client是能得到修改后的配置的,由此可以猜测config-client在启动时回去config-server拉取配置,在启动后如果需要拉取新的配置需要通知config-client去config-server获取,s如何告知?我们用到了springCloudBus-amqp,这里我们使用rabbitMQ。用下面的地址访问config-server,就会发布一个配置被修改的消息,所有的config-client收到消息后就会刷新配置啦。
当然每次修改后都访问这个链接有点太low,可以使用git仓库的hook功能实现每次代码提交后自动访问这个链接,这样就优雅得多了。如下码云的webHook(当然这里不能配localhost,必须配一个外网能访问的地址)
GIT-HOOK
网友评论