Spring Cloud Config是最早的配置中心,虽然后面的之秀Nacos可以取代它, 但是Spring Cloud Config还是很多公司在用,比如我司。
那为什么我们需要一个配置中心呢?我们直接将配置写在本地的yml配置文件中不行吗?
一个新技术的出现,一定是因为它解决了某些痛点,我们来看看将配置信息直接写在本地yml配置文件存在哪些痛点:
而Spring Cloud Config解决了这俩个痛点:
接下来,我们将根据这个架构图搭建一个案例。
项目中使用到的版本:
版本不同的话可能会出现一点问题。
首先我们需要一个创建一个配置中心仓库。由于github的网速太慢,所以我使用码云创建配置中心仓库,当然你也可以使用github。
1、在码云创建springcloud-config仓库
文件命名规格:{项目名}-{配置环境版本}.yml
。比如config-dev.yml,表示的是config项目的开发环境配置。
配置文件内容分别如下。
config-dev.yml:
user:
name: "张三 dev"
config-prod.yml
user:
name: "张三 prod"
1、 新建SpringBoot项目spring-cloud-config-server
,并引入依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Hoxton.SR1version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-serverartifactId>
dependency>
dependencies>
3.2 配置config相关配置
bootstrap.yml 文件
spring:
application:
name: config-server # 应用名称
cloud:
config:
server:
git:
# 配置中心仓库地址
uri: https://gitee.com/F_promise/springcloud-config.git #配置文件所在仓库
username: 码云用户名
password: 码云密码
default-label: master #配置文件分支
# search-paths: config #配置文件所在根目录
3、在 Application 启动类上增加相关注解 @EnableConfigServer
@SpringBootApplication
@EnableConfigServer
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class,args);
}
}
启动SpringBoot服务,测试一下。
Spring Cloud Config 有它的一套访问规则,我们通过这套规则在浏览器上直接访问就可以。
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
以第一条规则为例,访问config-dev.yml配置文件:
至此,配置中心服务端搭建完毕,接下来客户端(其他项目)需要从配置中心中获取配置信息。
1、新建SpringBoot项目spring-cloud-config-client
,并引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-configartifactId>
dependency>
dependencies>
注意,客户端和服务端引入的config依赖是不一样的。
2、编写bootstrap.yml配置文件
--- bootstrap.yml ---
spring:
profiles:
active: dev #激活开发环境的配置文件
---
spring:
application:
name: config
cloud:
config:
uri: http://localhost:8080 #config服务端的地址
label: master
profile: dev #开发环境
---
spring:
application:
name: config
cloud:
config:
uri: http://localhost:8080 #config服务端的地址
label: master
profile: prod #生产环境
3、编写application.yml配置文件
server:
port: 8888
user:
name: 小王 #配置默认值。配置中心有用配置中心的
4、创建UserController测试使用
@RestController
public class UserController {
@Value("${user.name}")
private String name;
@GetMapping("info")
public String info(){
return name;
}
}
5、启动服务,访问测试
可以看到,成功读取到了配置中心中的config-dev.yml配置文件。将bootstrap.yml中的active改成prod在进行测试:
Spring Cloud Config是在项目启动的时候加载的配置内容,导致了它存在一个缺陷,配置文件修改后,需要重启服务才能生效。这也是我们之前说的第二个痛点。
为了解决这个痛点,它提供了一个刷新机制,但是需要我们主动出发。那就是 @RefreshScope 注解并结合 actuator 。
1、在spring-cloud-config-client
加入actuator依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
2、在application.yml中添加如下actuator的配置
management:
endpoint:
shutdown:
enabled: false
endpoints:
web:
exposure:
include: "*"
3、在Controller上添加@RefreshScope注解
@RestController
@RefreshScope
public class UserController {
@Value("${user.name}")
private String name;
@GetMapping("info")
public String info(){
return name;
}
}
4、主动触发更新
在配置文件修改后,使用Postman发送一个post请求到http://localhost:8888/actuator/refresh 这个接口,触发主动更新。
Spring Cloud Bus 将分布式系统的节点与轻量级消息代理链接。这可以用于广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,Bus 就像一个扩展的 Spring Boot 应用程序的分布式执行器,但也可以用作应用程序之间的通信渠道。
—— Spring Cloud Bus 官方解释
如果每次配置文件修改后,都需要我们主动发送post请求触发更新,这明显有点不太方便。而且如何客户端比较多的话,一个一个的手动刷新也比较耗时。这个时候,我们可以借助Spring Cloud Bus的广播功能,让client端都订阅配置更新事件,当配置更新时,触发其中一个端的更新事件,Spring Cloud Bus就把此事件广播到其他订阅端,以此来达到批量更新。
1、Spring Cloud Bus 核心原理其实就是利用消息队列做广播,所以要先有个消息队列,目前官方支持 RabbitMQ 和 kafka。我们这里以RabbitMQ 为例。
2、在客户端spring-cloud-config-client
中加入依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bus-amqpartifactId>
dependency>
3、在配置文件中增加 RabbitMQ 相关配置
spring:
rabbitmq:
host: 192.168.243.136
port: 5672
username: guest
password: guest
4、启动俩个或多个客户端进行测试
我们可以拷贝一份配置
然后修改vm options添加-Dserver.port=8889就行了
所以最后的结构就是俩个客户端和一个配置中心服务端。
5、分别打开 http://localhost:8888/info和 http://localhost:8889/info,查看内容,然后修改码云上配置文件的内容并提交。再次访问这两个地址,数据没有变化。
6、访问其中一个的 actuator/bus-refresh 地址,注意还是要用 POST 方式访问。之后查看控制台输出,会看到这两个端都有一条这样的日志输出
o.s.cloud.bus.event.RefreshListener: Received remote refresh request. Keys refreshed
7、再次访问第 5 步的两个地址,会看到内容都已经更新为修改后的数据了。
以上是Spring Cloud Config最基本的使用,在实际开发中,Spring Cloud Config可能会被注册在Eureka中,这样的话,可以Spring Cloud Config配置中心就可以搭建集群实现高可用。
此外引入Eureka后,config客户端就不再需要直接和config服务端直接打交道了,而是通过Eureka来发现Config服务端。
首先搭建一个简单的Eureka。如果你没有学过Eureka的话,可以看看这篇文章Spring Cloud系列之Eureka入门使用。
1、导入依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
2、编写配置文件
spring:
application:
name: eureka-server
server:
port: 3000
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url.defaultZone: http://localhost:3000/eureka/
3、在启动类标记@EnableEurekaServer
注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
1、给spring-cloud-config-server
项目添加Eureka依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
2、在配置文件中添加Eureka相关配置
eureka:
client:
service-url:
#注册到eureka服务端的地址
defaultZone: http://localhost:3000/eureka/
instance:
#点击具体的微服务,右下角是否显示ip
prefer-ip-address: true
#显示微服务的名称
instance-id: spring-cloud-config-server
3、给主启动类添加@EnableEurekaClient
注解
1、给spring-cloud-config-client
项目添加Eureka依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
2、修改配置文件,添加Eureka的相关配置,并指定配置中心的application.name
spring:
profiles:
active: dev #激活开发环境的配置文件
eureka:
client:
service-url:
#注册到eureka服务端的地址
defaultZone: http://localhost:3000/eureka/
instance:
#点击具体的微服务,右下角是否显示ip
prefer-ip-address: true
#显示微服务的名称
instance-id: spring-cloud-config-client
---
spring:
application:
name: config
cloud:
config:
# uri: http://localhost:8080 #config服务端的地址,整合eureka后不需要填写
label: master
profile: dev #开发环境
discovery: #从Eureka中发现配置中心
enabled: true
service-id: config-server #指定配置中心的application.name
---
spring:
application:
name: config
cloud:
config:
# uri: http://localhost:8080 #config服务端的地址
label: master
profile: prod #生产环境
discovery: #从Eureka中发现配置中心
enabled: true
service-id: config-server #指定配置中心服务端的server-id
整合Eureka后,config客户端不再需要指定config服务端的地址,而是通过config服务端的application.name从Eureka中获取配置中心的信息。配置中心可以做集群高可用。
3、给主启动类添加@EnableEurekaClient
注解
启动后,查看Eureka,访问http://localhost:8888/info
进行测试。
参考文章:
https://cloud.tencent.com/developer/article/1474037