先回顾一下,在之前的Spring Cloud Config的介绍中,我们还留了一个悬念:如何实现对配置信息的实时更新。虽然,我们已经能够通过/refresh接口和Git仓库的Web Hook来实现Git仓库中的内容修改触发应用程序的属性更新。但是,若所有触发操作均需要我们手工去维护Web Hook中的应用位置的话,这随着系统的不断扩张,会变的越来越难以维护,而消息代理中间件是解决该问题最为合适的方案。是否还记得我们在介绍消息代理中的特点时有提到过这样一个功能:消息代理中间件可以将消息路由到一个或多个目的地。利用这个功能,我们就能完美的解决该问题,下面我们来说说Spring Cloud Bus中的具体实现方案。愿意了解源码的朋友直接求求交流分享技术 一七九一七四三三八零
RabbitMQ实现 下面我们来具体动手尝试整个配置过程:
准备工作:
config-repo:定义在Git仓库中的一个目录,其中存储了应用名为didispace的多环境配置文件,配置文件中有一个from参数。
config-server-eureka:配置了Git仓库,并注册到了Eureka的服务端。
config-client-eureka:通过Eureka发现Config Server的客户端,应用名为didispace,用来访问配置服务器以获取配置信息。该应用中提供了一个/from接口,它会获取config-repo/didispace-dev.properties中的from属性返回。
扩展config-client-eureka应用
修改pom.xml增加spring-cloud-starter-bus-amqp模块(注意spring-boot-starter-actuator模块也是必须的)。
在配置文件中增加关于RabbitMQ的连接和用户信息
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=springcloud
spring.rabbitmq.password=123456
启动config-server-eureka,再启动两个config-client-eureka(分别在不同的端口上,比如7002、7003),我们可以在config-client-eureka中的控制台中看到如下内容,在启动时候,客户端程序多了一个/bus/refresh请求。
o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/bus/refresh],methods=[POST]}" onto public void org.springframework.cloud.bus.endpoint.RefreshBusEndpoint.refresh(java.lang.String)
先访问两个config-client-eureka的/from请求,会返回当前config-repo/didispace-dev.properties中的from属性。
接着,我们修改config-repo/didispace-dev.properties中的from属性值,并发送POST请求到其中的一个/bus/refresh。
最后,我们再分别访问启动的两个config-client-eureka的/from请求,此时这两个请求都会返回最新的config-repo/didispace-dev.properties中的from属性。
到这里,我们已经能够通过Spring Cloud Bus来实时更新总线上的属性配置了。
指定刷新范围 上面的例子中,我们通过向服务实例请求Spring Cloud Bus的/bus/refresh接口,从而触发总线上其他服务实例的/refresh。但是有些特殊场景下(比如:灰度发布),我们希望可以刷新微服务中某个具体实例的配置。
Spring Cloud Bus对这种场景也有很好的支持:/bus/refresh接口还提供了destination参数,用来定位具体要刷新的应用程序。比如,我们可以请求/bus/refresh?destination=customers:9000,此时总线上的各应用实例会根据destination属性的值来判断是否为自己的实例名,若符合才进行配置刷新,若不符合就忽略该消息。
destination参数除了可以定位具体的实例之外,还可以用来定位具体的服务。定位服务的原理是通过使用Spring的PathMatecher(路径匹配)来实现,比如:/bus/refresh?destination=customers:**,该请求会触发customers服务的所有实例进行刷新。 完整项目源码