回到初衷,我们使用统一配置中心的目的是什么?便是更方便的管理我们的配置,还有就是当我们修改我们的配置时候,不需要重启我们的项目也可以依旧使我们的配置生效,这样是不就很方便了?
那么SpringCloud Bus是如何进行无感知的更新的呢?主要还是通过消息队列进行通知,下面简单说一下更新过程:
当我们的微服务端启动之后,开发过程中去修改了远程仓库git上的配置,这时候我们要读取到最新的配置必须得重启本地服务。这个时候我们引入SpringCloud Bus 这个消息队列,当git发生变化,springcloud bus 会通过访问 /bus-refresh这个接口把更新配置的消息发送到mq中,我们本地服务回到队列中去消费这条消息,达到最后的通知目的,最后无需重启项目也可以读到最新的配置。这里需要注意的【/bus-refresh】接口是post请求,一般我们会通过git上自带的WebHooks进行配置使用。下面案例中因为自己没有外网地址,这一步不作演示
我们演示的环境一共需要三个小demo:
1)注册中心Eureka
2)config server
3)config client ,我们这里模仿以order模块为例
注册中心Eureka的创建我们不在做演示,关于创建的详细过程请看【SpringCloud 之 Eureka注册中心的创建】
我们进行第二步config server的创建,因为引用了SpringCloud Bus,所以与之前的稍稍有些不同,我们再来创建一次
2.1)依旧我们选择如下图圈中的两个选项
2.2)修改版本,为了演示成功,请保持版本一致(其他版本可能遇到各种问题)
2.3)启动类添加注解:【@EnableDiscoveryClient】【@EnableConfigServer】
2.4)因为我们要使用【SpringCloud Bus】,所以我们引入相关引用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
2.5)配置文件中做如下详细配置
eureka:
client:
service.url:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: config
#配置我们的rabbitmq的相关信息,若是本地安装就不许需要配置,这里采用的是默认用户和密码
rabbitmq:
host: xxxx
port: 5672
username: guest
password: guest
#我们git上仓库地址,这里我使用的是开源中国的git库
cloud:
config:
server:
git:
uri: xxxxx
#用户名
username: xxxx
#密码
password: xxxx
#本地存放配置文件的地址,因为我们的配置中心会从从git上拉取配置文件然后存到本地一份,这个地址我们可以自定义配置
basedir: F:\config_basedir
#暴露我们需要定时刷新mq队列的的接口
management:
endpoints:
web:
exposure:
include: "*"
文件中可以看到我们配置了rabbitmq的地址,所以需要提到的就是我们这次演示必须安装RabbitMQ,我这里使用的是docker安装的,很简单就一句命令【docker run -d --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.8.3-management】
关于Centos 7 如何安装docker,详细可以看【Centos 7 之 安装 Docker 踩坑详解】
前面我们也提到了需要请求接口【bus-refresh】来发送消息进行通知,所以我们的配置中也相应的需要暴露接口
前两步基本准备就绪,我们启动进行访问一下先
2.6)访问Eureka,可以看到我们的config 的服务端已经注册上来了
访问我们的config server ,可以看到一切正常
访问我们的消息队列,可以看到已经有一个队列了,但是没有消息
一切正常,我们的所有配置都没有问题,接下来我们进行第三步config 客户端的创建
3.1)同样我们回顾一下创建过程,新建项目,做出如下图的选项
3.2)修改版本,为了演示成功,请保持版本一致(其他版本可能遇到各种问题)
3.3)启动类添加注解【@EnableDiscoveryClient】
3.4)pom文件引入相应的SpringCloud Bus配置(与服务端引入一样)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
3.5)配置文件做相关配置
spring:
application:
name: order
#配置我们的rabbitmq的相关信息,若是本地安装就不许需要配置,这里采用的是默认用户和密码
rabbitmq:
host: xxxx
port: 5672
username: guest
password: guest
cloud:
config:
discovery:
enabled: true
service-id: CONFIG
profile: dev
server:
port: 8090
eureka:
client:
service.url:
defaultZone: http://localhost:8761/eureka/
关于配置我们简单说明:
1)因为我们读取的配置文件名字叫做【order-dev.yml】,所以spring.application.name对应【order】;属性【profile】对应【dev】;然后就是spring.cloud.config.discovery.service-id对应的是注册在Eureka上的config Server的名字
2)就是我们的注册地址【spring.eureka.client.service.url.defaultZone】一定要写在我们这个config的客户端,因为当我们注册中心的地址端口对应的不是8761的时候(可能是8762),写在我们的git库配置文件中,启动项目会报错,会找不到我么的配置,原因是启动项目会先去找我们的注册中心eureka,找到之后才会在我们的【CONFIG】中找对应的配置,就是一个顺序的问题;
3)还有就是我们的配置文件名字最好是改成【bootstrap.yml】,因为我们真实的项目中,项目启动会读取数据库配置,找不到会报错,当我们改为bootstrap之后便会优先加载我们当前的配置文件,不再报错
4)配置我们的rabbitmq地址,若是在本机就无需配置
3.6)新建一个测试类
@RestController
@RequestMapping("/test")
@RefreshScope
public class TestController {
@Value("${env}")
private String env;
@Value("${lable}")
private String lable;
@GetMapping("/getEnv")
public String getEnv(){
return "env:"+env+",lable:"+lable;
}
}
一定要注意我们必须添加【RefreshScope】这个注解
3.7)我们启动项目访问 http://localhost:8090/test/getEnv,可以看到
eureka注册中心也注册成功
RabbitMQ队列也创建成功
环境一切就绪,接下里我们演示修改远端仓库配置文件无需重启项目即可生效的效果
首先我们修改远端git库的配置文件
我们将 【dev】 改成了【dev123456】
然后我们去请求发送消息的接口,去请求地址【http://localhost:8080/actuator/bus-refresh】来发送消息,告诉我们的客户端配置文件发生变动了,因为是post请求,我这里用postman来做请求,如下图,表示请求成功
最后我们无需重启项目,去访问我们的客户端 http://localhost:8090/test/getEnv,可以看到配置已经刷新
我们的配置自动刷新功能已经成功。
后续:关于去请求 http://localhost:8080/actuator/bus-refresh 接口 还需要我们postman手动刷新的事情,显然不够智能,这个可以使用我们git库的webhooks功能进行配置,配置之后便可以帮我们自动进行刷新了,因为我这里没有外网地址,就不做相应的演示了