springcloud学习(六)之Config
前言
在单体应用架构中,我们的配置文件比如application.yml可以每次手动维护,每次修改完之后重启项目即可。但在微服务架构中可能有多个微服务,涉及到的配置文件数量较多,如果每次手动维护的话会特别麻烦。
期望效果:
- 我们希望配置文件能够集中存储管理,且能实现一次修改、到处生效的效果;
- 不同 环境的配置文件是不同的,比如测试、生产、开发环境有不同的数据库连接地址;
- 服务运行期间配置能够动态调整。例如可以根据服务的负载情况动态调整数据源连接池大小等信息;
- 如果配置内容发生更改,微服务可以自动更新配置。
基于以上诉求,我们需要对文件进行集中式管理,也即分布式配置中心的作用。
Spring Cloud Config 简介
Spring Cloud Config是⼀个分布式配置管理⽅案,包含了 Server端和 Client端两个部分。
Server 端提供配置⽂件的存储、以接⼝的形式将配置⽂件的内容提供出去,通过使⽤@EnableConfigServer注解在 Spring boot 应⽤中⾮常简单的嵌⼊
Client 端通过接⼝获取配置数据并初始化⾃⼰的应⽤
Config简单搭建使用
Config Server是集中式的配置服务,⽤于集中管理应⽤程序各个环境下的配置。 默认使⽤Git存储配置⽂件内容,也可以SVN。
第一步, 码云上新建配置文件仓库:
- 登录码云,创建项⽬lagou-config-repo
- 上传yml配置⽂件,命名规则如下:
{application}-{profile}.yml 或者 {application}-{profile}.properties
其中, application为应⽤名称, profile指的是环境(⽤于区分开发环境,测试环境、⽣产环境等)
示例: lagou-service-resume-dev.yml、 lagou-service-resume-test.yml、 lagou-service-resume-prod.yml
第二步,构建Config Server 配置中心
新建SpringBoot⼯程,引⼊依赖坐标,
<!--eureka client 客户端依赖引⼊-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eurekaclient</artifactId>
</dependency>
<!--config配置中⼼服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
在启动类上添加注解@EnableConfigServer开启配置中⼼服务器功能
Spring:
application:
name: lagou-cofig-server
cloud:
config:
server:
git:
uri: https://gitee.com/mikecn/lagou-config-repo.git #配置git服务地址
username: 15028562592@163.com #配置git⽤户名
password: 6822992 #配置git密码
search-paths:
- lagou-config-repo
# 读取分⽀
label: master
启动类上添加@EnableConfigServer开启服务配置功能
浏览器访问:http://localhost:9006/master/lagou-service-resume-dev.yml
第三步,Client客户端配置:
我们在lagou-service-resume-8080这个服务中进行配置测试。
添加坐标:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
启动类上添加@EnableDiscoveryClient。
bootstrap.yml文件要比application的优先级高,所以我们将application.yml改为bootstrap.yml,在里面配置要拿到的文件地址信息:
spring:
cloud:
# config客户端配置,和ConfigServer通信,并告知ConfigServer希望获取的配置信息在哪个⽂件中
config:
name: lagou-service-resume #配置⽂件名称
profile: dev #后缀名称
label: master #分⽀名称
uri: http://localhost:9006 #ConfigServer配置中⼼地址
上面配置说明我们要去配置中心拿master分支上lagou-service-resume-dev这个文件的内容。
测试结果:
此时如果修改了git上的文件,比如
那么客户端拿不到最新的数据,因为客户端只是在服务最开始启动的时候才去加载一次配置文件。
我们需要配置一下手动刷新。
Config配置手动刷新
引入actuator的包(父工程已经引入),配置健康检查:
# springboot中暴露健康检查等断点接⼝
management:
endpoints:
web:
exposure:
include: "*"
Client客户端使⽤到配置信息的类上添加@RefreshScope
⼿动向Client客户端发起POST请求, http://localhost:8080/actuator/refresh,刷新配置信息.
此时向请求客户端配置信息,可以看到已经修改过的信息:
手动更新存在的问题:
我们需要每次都调用所有client配置客户端的接口才能更新每一个客户端的配置文件。这样在集群服务数量太多的情况下,显然是不合适的。能不能统一批量更新呢?或者说能不能调用一个接口就能实现全部客户端的同步更新,类似于广播机制。这就是Config的自动更新配置。
Config配置自动更新
在微服务架构中,我们可以结合消息总线(Bus)实现分布式配置的⾃动更新(Spring Cloud Config+Spring Cloud Bus)
消息总线Bus
所谓消息总线Bus,即我们经常会使⽤MQ消息代理构建⼀个共⽤的Topic,通过这个Topic连接各个微服
务实例, MQ⼴播的消息会被所有在注册中⼼的微服务实例监听和消费。 换⾔之就是通过⼀个主题连接
各个微服务,打通脉络。
Spring Cloud Bus(基于MQ的,⽀持RabbitMq/Kafka) 是Spring Cloud中的消息总线⽅案, Spring
Cloud Config + Spring Cloud Bus 结合可以实现配置信息的⾃动更新。
Spring Cloud Config+Spring Cloud Bus 实现⾃动刷新
注意:需要安装RabbitMQ,安装教程参加附录。
ConfigServer和ConfigClient都添加消息总线的⽀持以及与RabbitMq的连接信息。
主要步骤如下(完整参见附录源码):
在所有config客户端及config server中做如下配置:
- 添加如下mq的jar包:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- application.yml中配置mq的地址:
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
- application.yml中添加健康监控:
# springboot中暴露健康检查等断点接⼝
management:
endpoints:
web:
exposure:
include: "*"
- 重启各个服务,更改配置之后,向配置中心发送post请求:
http://localhost:9006/actuator/bus-refresh
,各个客户端配置就会在广播模式下自动同步更新。
上述操作实现了一次请求处处更新。如果我只想定向更新的话,比如我只想更新8081客户端的配置,应该如何操作呢?
http://localhost:9006/actuator/bus-refresh/lagou-service-resume:8081
在发起刷新请求的时候在后面加上要定向刷新的实例服务名称:端口号即可。
附录
案例源码
config案例源码地址:config案例源码地址
参考文章
欢迎访问我的博客:https://www.liuyj.top