前言
先回顾一下,在之前的spring Cloud Config的介绍中,我们还留了一个悬念:如何实现对配置信息的实时更新。虽然,我们已经能够通过/refresh接口,但是,若所有触发操作均需要我们手工去维护应用位置的话,这随着系统的不断扩张,会变的越来越难以维护,而消息代理中间件是解决该问题最为合适的方案,消息代理中间件可以将消息路由到一个或多个目的地。利用这个功能,我们就能完美的解决该问题,下面我们来说Spring Cloud Bus中的具体实现方案。
原理分析
我们通过使用Spring Cloud Bus与Spring Cloud Config的整合,并以Kafka作为消息代理,实现了应用配置的动态更新。
整个方案的架构如上图所示,其中包含了Svn仓库、Config Server、以及微服务“Service A”的三个实例,这三个实例中都引入了Spring Cloud Bus,所以他们都连接到了Kafka的消息总线上。
当我们将系统启动起来之后,“Service A”的三个实例会请求Config Server以获取配置信息,Config Server根据应用配置的规则从Svn仓库中获取配置信息并返回。
此时,若我们需要修改“Service A”的属性。首先,通过Svn管理工具去仓库中修改对应的属性值,但是这个修改并不会触发“Service A”实例的属性更新。我们向“Service A”的实例3发送POST请求,访问/bus/refresh接口。此时,“Service A”的实例3就会将刷新请求发送到消息总线中,该消息事件会被“Service A”的实例1和实例2从总线中获取到,并重新从Config Server中获取他们的配置信息,从而实现配置信息的动态更新。
使用实例
准备
下面我们来具体动手尝试整个配置过程:
准备工作:这里我们不做新的应用,但需要用到上一章中,我们已经实现的关于Spring Cloud Config的几个工程,若读者对其还不了解,建议先阅读第6章的内容。
- cloudConfig:定义在Svn仓库中的一个目录,其中存储了应用名为didispace的多环境配置文件,配置文件中有一个from参数。
- config-server-eureka:配置了Svn仓库,并注册到了Eureka的服务端。
- config-client-eureka:通过Eureka发现Config Server的客户端,应用名为didispace,用来访问配置服务器以获取配置信息。该应用中提供了一个/from接口,它会获取\cloudConfig\config-repo\didispace.properties中的from属性返回。
整合Spring Cloud Bus
若我们要使用Kafka来实现消息总线时,只需要把spring-cloud-starter-bus-kafka模块,在pom.xml的dependenies节点中进行修改,具体如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
如果我们在启动Kafka时均采用了默认配置,那么我们不需要再做任何其他配置就能在本地实现Kafka。我们可以尝试把刚刚搭建的ZooKeeper、Kafka启动起来,并将修改为spring-cloud-starter-bus-kafka模块的config-server和config-client启动起来。
在config-server启动时,我们可以在控制台中看到如下输出:
此时,我们可以使用kafka-topics --list --zookeeper localhost:2181命令来查看当前Kafka中的Topic,若已成功启动了config-server并配置正确,我们就可以在Kafka中看到已经多了一个名为springCloudBus的Topic。
我们再启动配置了spring-cloud-starter-bus-kafka模块的config-client,可以看到控制台中输出如下内容:
可以看到,config-client启动时输出了类似的内容,他们都订阅了名为springCloudBus的Topic。
在启动了config-server和config-client之后,为了更明显地观察消息总线刷新配置的效果,我们可以在本地启动多个不同端口的config-client。此时,我们的config-server以及多个config-client都已经连接到了由Kafka实现的消息总线上。我们可以先访问各个config-client上的/from请求,查看他获取到的配置内容。然后,修改Svn中对应的参数内容,再访问各个config-client上的/from请求,可以看到配置内容并没有改变。最后,我们向config-server发送POST请求:/bus/refresh,此时我们再去访问各个config-client上的/from请求,就能获得到最新的配置信息,各客户端上的配置都已经加载为最新的Svn配置内容
(curl -X POST http://IP:7002/bus/refresh)。
从config-client的控制台中,我们可以看到如下内容:
RefreshListener监听类记录了收到远程刷新请求,并刷新了from属性的日志。