SpringCloud学习Day09

注:本教程均是参考"程序猿DD"大佬的SpringCloud教程:http://blog.didispace.com/spring-cloud-learning/实践结合自己的理解和总结编写

spring cloud bus
在SpringCloud学习Day02学习中我们学习了分布式配置更新,并且在最后实现了配置的动态刷新,现在如果对于一个微服务我们有多个实例,该怎么动态刷新局部或者全部的配置呢,按需调用/refresh接口?或者是通过git仓库的WebHook配置多个实例的/refresh接口,随着系统的不断扩张,会变的越来越难以维护,通过消息代理中间件,spring cloud bus帮我们完美解决了问题

动手实验:
在原有config-client项目基础上
1.添加pom.xml


    org.springframework.cloud
    spring-cloud-starter-bus-amqp

2.bootstrap.properties

spring.rabbitmq.host=192.168.1.232
spring.rabbitmq.port=5672
spring.rabbitmq.username=gymqadmin
spring.rabbitmq.password=gymqadmin1397
spring.rabbitmq.virtual-host=INFO

3.复制config-client到config-client2、config-client3并分别修改spring.application.name和server.port;
老弟在这里遇到了问题,在参照“程序猿DD”教程系列时,config-client的bootstrap.properties配置连接到配置中心的配置为

spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.profile=dev
spring.cloud.config.label=master

在启动config-client2时,连接不上配置中心,控制台日志输出连接配置中心地址为https://github.com/SpringStudent/config-client2/config-client-dev.properties,然后导致连接失败报错,然后查阅资料发现少了配置

spring.cloud.config.name=config-client

如果不指定该配置的话,会读取spring.application.name配置名称,源码如下

SpringCloud学习Day09_第1张图片

4.依次启动eureka-server、config-server、config-client、config-client2、config-client3
然后访问config-client实例的/from接口,可以看到返回的属性
5.修改配置中心config-client/config-client-dev.properties,通过postman调用config-client/config-client2/config-client/3任意一个服务的接口如下

POST http://ip:port/bus/refresh

6.重新访问config-client/config-client2/config-client3的/from接口可以看到所有配置均已刷新

原理分析

SpringCloud学习Day09_第2张图片

整个方案的架构如上图所示,其中包含了Git仓库、Config Server、以及微服务“Service A”的三个实例,这三个实例中都引入了Spring Cloud Bus,所以他们都连接到了RabbitMQ的消息总线上。
当我们将系统启动起来之后,“Service A”的三个实例会请求Config Server以获取配置信息,Config Server根据应用配置的规则从Git仓库中获取配置信息并返回。
此时,若我们需要修改“Service A”的属性。首先,通过Git管理工具去仓库中修改对应的属性值,但是这个修改并不会触发“Service A”实例的属性更新。我们向“Service A”的实例3发送POST请求,访问/bus/refresh接口。此时,“Service A”的实例3就会将刷新请求发送到消息总线中,该消息事件会被“Service A”的实例1和实例2从总线中获取到,并重新从Config Server中获取他们的配置信息,从而实现配置信息的动态更新。
而从Git仓库中配置的修改到发起/bus/refresh的POST请求这一步可以通过Git仓库的Web Hook来自动触发。由于所有连接到消息总线上的应用都会接受到更新请求,所以在Web Hook中就不需要维护所有节点内容来进行更新,从而解决了通过Web Hook来逐个进行刷新的问题。

灰度发布配置刷新
/bus/refresh接口支持destination参数,用于指定 要刷新的应用程序,比如/bus/refres?destination=
${spring.application.name}:${server.port},此时会根据destination配置判断自己的实例是否需要刷新,符合destination参数配置进行刷新,否则忽略消息
destination参数除了可以定位具体的实例之外,还可以用来定位具体的服务。定位服务的原理是通过使用Spring的PathMatecher(路径匹配)来实现,比如:/bus/refresh?destination=customers:**,该请求会触发customers服务的所有实例进行刷新

架构优化
既然Spring Cloud Bus的/bus/refresh接口提供了针对服务和实例进行配置更新的参数,那么我们的架构也相应的可以做出一些调整。在之前的架构中,服务的配置更新需要通过向具体服务中的某个实例发送请求,再触发对整个服务集群的配置更新。虽然能实现功能,但是这样的结果是,我们指定的应用实例就会不同于集群中的其他应用实例,这样会增加集群内部的复杂度,不利于将来的运维工作,比如:我们需要对服务实例进行迁移,那么我们不得不修改Web Hook中的配置等。所以我们要尽可能的让服务集群中的各个节点是对等的。

SpringCloud学习Day09_第3张图片

  • 1.在config-server中引入spring cloud bus,将配置服务加入到消息总线
  • 2./bus/refresh请求不发到具体服务而是发送给config-server,通过destination参数指定需要更新配置的服务或实例
     

你可能感兴趣的:(SpringCloud)