使用Spring Cloud Bus来实现配置文件的动态更新原理很简单,当我的配置文件更新后,我向Config-Server中发送一个/bus/refresh请求,Config-Server收到这个请求之后,会将这个请求广播出去,这样所有的微服务就都收到这个请求了,微服务收到这个请求之后就会自动去更新自己的配置文件。在这个系统中,从RabbitMQ的角度来看,所有的微服务都是一样的,所以这个/bus/refresh请求我们也可以在微服务节点上发出,一样能够实现配置文件动态更新的效果,但是这样做就破坏了我们微服务的结构,使得微服务节点之间有了区别,所以刷新配置的请求我们还是放在Config-Server上来做比较合适。
1. 先构建一个配置中心,并注册到注册中心
1)首先我们来构建一个配置中心,方式很简单,创建一个普通的Spring Boot项目,叫做config-server,创建好之后,添加如下依赖:(20-springcloud-bus-center)
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--添加配置中心的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!--添加服务注册和发现依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!--添加配置中心的安全保护依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!--添加 微服务Spring Cloud Bus 依赖 通过使用cloud-config 与cloud-bus的整合,并用rabbitMQ为消息代理, 实现多个应用配置的动态更新。 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2)在入口类上添加@EnableConfigServer注解,表示开启配置中心服务端功能,如下:
@EnableDiscoveryClient // 服务注册与发现 @EnableConfigServer @SpringBootApplication public class BusCenterApplication { public static void main(String[] args) { SpringApplication.run(BusCenterApplication.class, args); } }
3)在application.properties中配置一下git仓库的信息以及服务注册的地址:
server.port=3001 spring.application.name=bus-center #向服务注册中心注册服务 eureka.client.service-url.defaultZone=http://localhost:1110/eureka/ #仓库配置中心的配置信息: #uri表示配置中心所在仓库的位置 spring.cloud.config.server.git.uri=https://github.com/lihy2018/newRepo.git #search-paths表示仓库下的子目录 spring.cloud.config.server.git.search-paths=config-repo #username表示你的GitHub用户名 spring.cloud.config.server.git.username=**** #password表示你的GitHub密码 spring.cloud.config.server.git.password=**** #更改本地仓库clone的配置文件信息的路径 spring.cloud.config.server.git.basedir=D:\\localGitRepo\\ #安全保护 security.user.name=***** security.user.password=***** #添加BUS 连接到RabbitMQ服务器上的信息 spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=test spring.rabbitmq.password=test
4) 通过本地的git命令, 向github远程仓库上提交配置文件( 具体步骤请查看上一篇)
2.构建一个配置客户端
1)首先创建一个普通的Spring Boot工程config-client,创建成功之后添加如下依赖:(20-springcloud-bus-client)
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--添加config 客户端的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!--添加服务注册和发现依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!--添加 重试机制 的依赖 因网络的抖动等原因导致config-client在启动时候访问config-server没有访问成功从而报错, 希望config-client能重试几次,故重试机制 --> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- 动态刷新配置 更新了Git仓库中的配置文件,那如何让config-client能够及时感知到呢? 动态刷新配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--添加 微服务Spring Cloud Bus 依赖 通过使用cloud-config 与cloud-bus的整合,并用rabbitMQ为消息代理, 实现多个应用配置的动态更新。 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2)创建bootstrap.properties文件,来获取配置信息,注意这些信息一定要放在bootstrap.properties文件中才有效,文件内容如下:
server.port=3003 spring.application.name=app-client #配置客户端信息 spring.cloud.config.profile=prod spring.cloud.config.label=master #指定动态刷新某个微服务的配置http://localhost:3002/bus/refresh?destination=app:3002 #每一个实例的instance-id是spring.application.name和{server.port}共同组成。 #http://localhost:3002/bus/refresh?destination=app:3002, # destination后面指定要更新的实例的instance-id eureka.instance.instance-id=${spring.application.name}:${server.port} #服务注册发现配置 eureka.client.service-url.defaultZone=http://localhost:1110/eureka/ #表示开启通过服务名来访问config-server spring.cloud.config.discovery.enabled=true #表示注册中心config-server的服务名 spring.cloud.config.discovery.service-id=bus-center #启动失败时能够快速响应 spring.cloud.config.fail-fast=true #安全保护 spring.cloud.config.username=***** spring.cloud.config.password=***** #动态刷新配置 ---需要忽略权限拦截 management.security.enabled=false
3) 在application.properties中配置 重试机制
#和重试机制相关的配置有如下四个: # 配置重试次数,默认为6 spring.cloud.config.retry.max-attempts=6 # 间隔乘数,默认1.1 spring.cloud.config.retry.multiplier=1.1 # 初始重试间隔时间,默认1000ms spring.cloud.config.retry.initial-interval=1000 # 最大间隔时间,默认2000ms spring.cloud.config.retry.max-interval=20004) 在入口类上添加@EnableDiscoveryClient注解,表示开启服务注册与发现功能,如下:
@EnableDiscoveryClient @SpringBootApplication public class BusClientApplication { public static void main(String[] args) { SpringApplication.run(BusClientApplication.class, args); } }5)编写controller
@RestController @RefreshScope public class HelloController { @Value("${sang}") private String sang; @Autowired private Environment environment ; @RequestMapping("/hello1") public String getHello(){ return this.sang; } @RequestMapping("/hello2") public String getHello2() { return environment.getProperty("sang", "未定义"); } }
3.依程序启动服务注册中心,配置中心config-server , 配置客户端app-client(启动两个服务,端口分别为3002, 3003 )
4.访问服务 http://localhost:3002/hello2 或者 http://localhost:3003/hello2
然后使用本地的git 修改配置文件app-prod.properties ,然后提交、push到远程仓库Github上。
继续访问服务 http://localhost:3002/hello2 或者 http://localhost:3003/hello2 ,此时访问的结果会不是最新的,
需要使用postman post请求访问 http://localhost:3002/bus/refresh
然后再访问http://localhost:3002/hello2 或者 http://localhost:3003/hello2 时,可以看到是两个服务都能访问到最新的结果啦。
这是结合 Bus来实现配置文件的动态更新,向Config-Server中发送一个/bus/refresh请求,Config-Server收到这个请求之后,会将这个请求广播出去,这样所有的微服务就都收到这个请求了,微服务收到这个请求之后就会自动去更新自己的配置文件。