一、简介
- 配置中心是微服务架构中一个重要的组件,主要用来专门统一管理各环境的配置信息,Spring Cloud Config 为分布式系统中的外部化配置提供服务器端和客户端支持。当我们的应用从开发到测试再进入生产时,我们呢可以通过修改配置来切换各个环境。
二、文档说明
- 该文档需要搭建一个eureka注册中心,源码中bike-business是作为客户端使用的,即客户端的配置都在bike-business项目里
- 关于配置文件的代码,其中只包含了注册中心相关的配置,如果查看完整的配置,请查看源码
- 该项目采用的是springboot2.4.X其中有些地方的配置与低版本会有不一样的地方,注意boot版本即可
二、配置服务端Config Server
-
pom文件
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> -
创建git仓库
1、在git上创建存储配置文件的仓库
2、也可以指定本地文件的地址进行测试
-
配置文件
spring: application: name: bike-config cloud: config: server: git: #uri只能到仓库名 uri: https://gitee.com/bike-project/bike-repo #配置多个仓库,如果该配置下没有匹配到对应的配置文件,那么会通过同级的git.uri地址匹配配置文件 repos: #应用名:即业务系统的spring.application.name值 bike-business: #仓库地址 uri: https://gitee.com/bike-project/bike-business #配置文件存储目录可使用通配符规则是:[目录]/[环境](即spring.profile.avctive的值) #这是一个list,可配置多个 pattern: - bike-business/sit* - bike-business/prod* bike-business2: uri: https://gitee.com/bike-project/bike-business2 pattern: - bike-business2/sit* - bike-business2/prod* #设置fals来禁用ssl验证,默认为true skipSslValidation: true username: username password: password #多层目录search-paths 就从根目录开始写起 search-paths: bike-business #分支设置 default-label: master #超时设置 timeout: 5 #如果本地副本变脏,可设置此参数强制从远程更新 force-pull: true #在启动服务时识别错误的配置(比如无效的数据库url),如果为false则可能不会报错,知道其他应用请求时才会识别错误 clone-on-start: true #服务启动时会将远程分支clone的本地库,如果远程分支删除,那么本地分支还是可用状态,一直到下次重启,这时候我们可以设置 #这个参数为true,默认时false,从本地存储库中强制删除未跟踪的分支 delete-untracked-branches: true #刷新率属性单位为秒,默认为0,这意味着配置服务器将在每次请求时从 Git 存储库中获取更新的配置 refresh-rate: 4 #配置用户名和密码来读取配置 security: user: name: user password: password -
启动类
添加@EnableConfigServer注解即可
@SpringBootApplication @EnableConfigServer public class BikeConfigApplication { public static void main(String[] args) { SpringApplication.run(BikeConfigApplication.class, args); } } -
验证
启动项目,访问http://Ip:port/application-dev.yml如果能查看到git仓库配置文件的信息服务器配置成功
-
总结
-
服务启动时,会从git仓库clone到一个本地仓库,我们获取的都是本地仓库的数据
-
我们可配置刷新速率来保证获取最新的配置,后面还有消息总线,自动刷新等策略
-
对于配置中心,我们习惯性把客户端的引导配置文件起名为bootstrap.yml而不是原来的application.yml,加载配置的优先级是不一样的,bootstrap.yml加载优先级更高,对于仓库的配置文件名称一般还是使用原来的application.yml,他也有多种命名规则,加载优先级也不一样,平时用的不多,这里就不多做分析了。
-
如果boot2.4.X以上版本使用bootstrap.yml,需要引入包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
-
三、配置客户端 Client Server
-
pom配置
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> -
配置文件
-
bootstrap.yml 作为启动引导文件
server: port: 8122 spring: profiles: active: dev -
bootstrap-dev.yml
spring: application: name: bike-business cloud: config: #如果服务端配置了用户名密码,那这里也需要设置 uri: http://user:password@127.0.0.1:8127 discovery: service-id: bike-config enabled: true profile: dev #读取超时设置 request-read-timeout: 5000 #连接超时时间 request-connect-timeout: 50000 #如果连接不到配置服务器,想快速异常停止,可配置为true,默认为false fail-fast: true # 重试机制,配置重试首先需要配置上面的fail-fast:true # 如果要完全控制重试,请使用id“configServerRetryInterceptor”添加RetryOperationsInterceptor类型的@Bean。Spring Retry有一个RetryInterceptorBuilder,可以轻松创建一个 retry: #第一次与第二次时间间隔 initial-interval: 1000 #最大间隔 max-interval: 1500 #等待最大值 max-attempts: 10000 #上一次尝试时间间隔的乘数 multiplier: 2 ##Config Client 提供了一个 Spring Boot Health Indicator,它尝试从 Config Server 加载配置。可以通过设置禁用健康指示器health.config.enabled=false。出于性能原因,响应也被缓存。默认缓存生存时间为 5 分钟。要更改该值,请设置该health.config.time-to-live属性(以毫秒为单位) #health: # config: # time-to-live: -
实例代码
/** * @author :Nickels * @date :2021/4/26 * @desc : */ @RestController @RequestMapping("/bike-business") public class BusinessController { @Value("${server.port}") String port; @Value("${env}") String env; @GetMapping("/hello") public String helloBusiness(){ System.out.println("hello business port : 8122 ....."); return "hello business port : 8122 ....."; } @GetMapping("/env") public String env(){ return port + " : " + env + " : "; } } -
验证
启动项目,访问接口,能够获取远程服务器的配置参数即可成功
-
总结
-
目前设置了用户名和密码但是好像没生效,需要进一步研究。
-
如果boot2.4.X以上版本使用bootstrap.yml,需要引入包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
-
-
四、消息总线bus
-
介绍
Spring Cloud Bus 将分布式系统的节点与轻量级消息代理连接起来。Spring Cloud Config 负责从Git服务器clone配置提供给其他应用,Spring Cloud Bus可以使用此代理来广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,总线就像一个用于横向扩展的 Spring Boot 应用程序的分布式执行器。但是,它也可以用作应用程序之间的通信渠道。该项目为 AMQP 代理或 Kafka 提供启动器作为传输。
-
架构机制
-
自动刷新使用了github的webhooks配置,配置好url和事件,当我们触发事件时,会触发url地址的post调用
-
客户端刷新
通过上图可以看出bus的刷新机制
- 提交代码触发post给客户端A发送bus/refresh
- 客户端A接收到请求从Server端更新配置并且发送给Spring Cloud Bus
- Spring Cloud bus接到消息并通知给其它客户端
- 其它客户端接收到通知,请求Server端获取最新配置
- 全部客户端均获取到最新的配置
这种方式破坏了微服务的职责单一原则和服务节点的对称性,业务系统更多的只是关注自身业务,不应该由某一业务系统再去承担刷新配置的功能。所以我们在此基础上,可选择第二种方式,有配置服务器来承担刷新配置功能。
-
服务端刷新
通过上图看出bus的刷新机制由客户端转为了服务端
-
提交代码触发post给Server端发送bus/refresh
-
Server端接收到请求并发送给Spring Cloud Bus
-
Spring Cloud bus接到消息并通知给其它客户端
-
其它客户端接收到通知,请求Server端获取最新配置
-
全部客户端均获取到最新的配置
-
-
-
配置改动
-
服务端改动
-
添加依赖
<!-- 消息总线 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> -
配置文件
spring: application: name: bike-config cloud: config: server: git: #uri只能到仓库名 uri: https://gitee.com/bike-project/bike-repo username: ****** password: ****** #多层目录search-paths 就从根目录开始写起 search-paths: bike-business #分支 default-label: master #r如果本地副本变脏,可设置此参数强制从远程更新 force-pull: true #用于开启开启/关闭 AckRemoteApplicationEvent 事件的发送。 ack: enabled: true #用于开启/关闭全局刷新的 Listener refresh: enabled: true #用于开启/关闭消息记录 Trace 的 Listener trace: enabled: true #用于开启/关闭配置新增/修改的 Endpoint env: enabled: true #配置用户名和密码来读取配置 security: user: name: admin password: admin123 #bus启用的是RabbitMQ 或 Kafka两种代理,我们选择的是RabbitMQ,所以要添加RabbitMQ配置 rabbitmq: host: server-host port: 5672 username: **** password: **** management: endpoints: web: exposure: include: '*' endpoint: busrefresh: enabled: true
-
-
客户端改动
-
添加依赖
<!-- 消息总线 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> -
配置文件
spring: cloud: config: #如果服务端配置了用户名密码,那这里也需要设置 uri: http://admin:admin123@127.0.0.1:8127 discovery: service-id: bike-config enabled: true profile: sit #读取超时设置 request-read-timeout: 5000 #连接超时时间 request-connect-timeout: 50000 #如果连接不到配置服务器,想快速异常停止,可配置为true,默认为false fail-fast: true # 重试机制,配置重试首先需要配置上面的fail-fast:true # 如果要完全控制重试,请使用id“configServerRetryInterceptor”添加RetryOperationsInterceptor类型的@Bean。Spring Retry有一个RetryInterceptorBuilder,可以轻松创建一个 retry: #第一次与第二次时间间隔 initial-interval: 1000 #最大间隔 max-interval: 1500 #等待最大值 max-attempts: 10000 #上一次尝试时间间隔的乘数 multiplier: 2 #客户端也需要添加mq配置来消费消息 rabbitmq: host: server-host port: 5672 username: **** password: ****
-
-
Controller修改
只需要在引用配置文件参数的类上添加@RefreshScope注解
@RestController @RequestMapping("/bike-business") @RefreshScope//添加注解 public class BusinessController { @Value("${server.port}") String port; @Value("${env}") String env; @GetMapping("/hello") public String helloBusiness(){ System.out.println("hello business port : 8125....."); return "hello business port : 8125 ....."; } @GetMapping("/env") public String env(){ return port + " : " + env; } }
-
-
测试验证
-
依次启动bike-config(配置服务器),bike-business(客户端1),bike-business2(客户端2)
-
观察mq管理界面注册队列,默认的是topic交换机,注册了三个队列说明配置已经生效成功
-
修改码云配置文件参数env
-
通过postman模拟执行刷新配置接口,执行post请求
-
如果对于多个节点部署,只需要更新部分节点的参数可执行下面的post请求
- http://config-server-host:config-server-port/actuator/busrefresh/bike-business:8122
- 路径参数为:服务名:服务端口号,如果只更新该服务的所有节点参数,则可以设置为:服务名:**,例如:
bike-business:**意为business下面的所有节点更新配置。低版本可能设置destination参数也可以指定节点更新配置,但是2.4.X版本测试参数并未生效,执行后还是所有应用更新配置,如果低版本可以尝试下http://config-server-host:config-server-port/actuator/busrefresh?destination=bike-business:8122这种方式。
-
请求不同的业务系统接口,观察获取的配置信息是否修改即可
-
官方地址:Spring Cloud Config
中文地址:中文地址
官方地址:Spring Cloud Bus
中文地址:中文地址
源码地址:源码