Spring Cloud Bus利用消息中间件来连接分布式系统中的各个节点,用来广播状态的改变,比如配置文件的改变,以及管理指令。
这里我们利用rabbitmq来作为消息中间件,项目结构由一台eurekaServer,一台configServer,不同端口的2台app1。configServer作为服务方注册到eurekaServer,rabbitmq的安装不多介绍了。
app1作为消费方,向eurekaServer订阅configServer的服务。
eurekaServer项目就不多介绍了。
configServer在启动类加上注解EnableEurekaClient,在配置文件加上eurekaServer的地址。
app1启动类:
@SpringBootApplication
@RestController
@EnableEurekaClient
@RefreshScope //一定要加上。
public class App1Application {
public static void main(String[] args) {
SpringApplication.run(App1Application.class, args);
}
/**
* config server连接的远程资源库和本地application.properties都提供
* 优先取config server上配置app1-config1.properties
* 若没有,则取application.properties配置
*/
@Value("${username}")
private String username;
/**
* config server没有提供该配置,取application.properties
*/
@Value("${year}")
private Integer year;
/**
* 取config server上配置app1-config2.properties,注意这里是资源库上另外一个配置文件
*/
@Value("${address}")
private String address;
/**
* 从application.properties, application.yml, application-*.properties取全局配置。
*/
@Value("${greeting}")
private String greeting;
@RequestMapping(value = "/hello")
public String hello() {
return username + ":" + year + ":" + address + ":" + greeting;
}
}
application.properties里加上rabbitMq配置:
server.port=8881
username = 张三
year = 18
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
bootstrap.properties:
spring.application.name= app1
spring.cloud.config.label= master
spring.profiles.active = config1,config2
#从注册中心取配置服务器的服务
eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka/
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
spring.cloud.client.registerWithEureka= false
在app1和configserver上都加上rabbitmq的依赖,他们都可以用/bus/refresh端点来刷新配置。
org.springframework.cloud
spring-cloud-starter-bus-amqp
依次启动eurekaServer,configServer,app1端口分别为8881,8882的4个应用。
访问8881和8882都是一样结果
我们去git上更改配置项,刷新上面页面,是没有实时生效的,怎么办呢,我们发送post请求:localhost:8881/bus/refresh.
响应200,成功,看下日志:
刷新了username,我们改的这个配置项。
再去刷新8881,8882端口的页面。
OK,生效了,很快,几乎没什么延迟。
上面我们是在8881上发起的刷新请求,8882上也同步刷新了,为什么呢,因为他们端口虽然不一样,但他们的应用名是一样的,而我们更改文件中的配置项时,/bus/refresh请求,会通知该配置项所在文件的文件名对应的所有应用,比如:更改的文件名是app1-dev.properties,那么它会通知所有应用名为app1的应用重新拉取配置项,重新初始化环境。
我们能不能再configserver上发起/bus/refresh请求呢,试试看。
OK,返回200,刷新成功。看下页面效果。
我们可以看到,端口8881的应用拉取了最新的配置项。
所以,当配置项更改是,我们不仅可以再客户端刷新,也可以再服务端刷新。
源码:https://github.com/bawcwchen/springCloudBusDemo.git