前言
欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud。
本系列适合有一定Java以及SpringBoot基础的同学阅读。
配置中心客户端主动刷新机制 + 配置中心服务化和高可用改造
客户端Refresh:客户端主动获取配置信息
经过上一章节配置好Spring Cloud Config后,客户端(config-client模块)能够获得从服务端(config-server模块)传来的配置文件信息。
文末写出了一个问题,客户端并不能获取更新后的配置信息,想要刷新信息,必须重启config-client模块,这显然不切实际。
实验:验证客户端无法更新
下面做一个实验,启动客户端和服务端,随后更新dev配置文件,新加了(new):
随后push到远程仓库,我们再次直接访问服务端的 http://localhost:8769/spring-cloud-config-dev.properties :
发现更新成了新的配置文件。
之后访问客户端:
发现依然是老的配置文件信息,客户端只在启动时获取了当时的配置文件信息。
开启更新机制
我们只需要在config-server模块中进行改动。
实现Refresh机制需要添加依赖spring-boot-starter-actuator,这个依赖在我们的root模块中就已经添加,在config-server模块就不需要重复添加了。如果你在root父模块没有添加,那么就需要加上。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 复制代码
对于springboot 1.5.X 以上版本,需要在配置文件中关闭安全认证。
management.security.enabled=false 复制代码
对于springboot 2,上述配置不起作用,需要修改server端配置文件,将端口暴露:
management: endpoints: web: exposure: include: "*" 复制代码
还要将客户端端口暴露:
management: endpoints: web: exposure: include: refresh 复制代码
测试:
我们开启服务端和客户端,先测试下未更新前获取的配置信息:
随后我们修改配置文件并push:
然后以post请求访问 curl -v -X POST "http://localhost:8002/actuator/refresh"
:
得到了:
如果在不变更的情况下,再次发送POST请求:
使用Webhook监听配置更新
WebHook是当某个事件发生时,通过发送http post请求的方式来通知信息接收方。Webhook来监测你在Github.com上的各种事件,最常见的莫过于push事件。如果你设置了一个监测push事件的Webhook,那么每当你的这个项目有了任何提交,这个Webhook都会被触发,这时Github就会发送一个HTTP POST请求到你配置好的地址。
如此一来,你就可以通过这种方式去自动完成一些重复性工作,比如,你可以用Webhook来自动触发一些持续集成(CI)工具的运作,比如Travis CI;又或者是通过 Webhook 去部署你的线上服务器。下图就是github上面的webhook配置。
这种机制适用于只有少数微服务的情况,在大量未服务的情况下,这种机制就显得捉襟见肘。
消息总线机制
如果项目少配置少的情况可以通过/refresh来手动刷新配置,如果项目比较复杂的情况呢这种肯定是行不通的,Spring Cloud Bus消息总线可以解决配置修改的真正的动态刷新。我们放在下一章进行学习。
配置中心服务化和高可用改造
目前我们的两个子模块config-server和config-client是相互耦合的,client需要输入server的地址来调用它,这样的调用违反了低耦合原则(低耦合:就是A模块与B模块存在依赖关系,那么当B发生改变时,A模块仍然可以正常工作,那么就认为A与B是低耦合的。)
现在我们就是用之前学习的Eureka来对配置中心进行改造。
服务端改造
改造集中在两方面,一个是在注册中心注册,一个是开启多个服务端达到高可用的目的。
添加依赖(由于eureka的依赖在我们的父模块已经添加,所以对于config-server模块我们不需要改动):
<dependencies> <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> </dependencies> 复制代码
配置文件新增注册配置:
server: port: 8769 spring: application: name: spring-cloud-config-server cloud: config: server: git: uri: https://xxxxxxxxxxx.git # 配置git仓库的地址 search-paths: config-repo # git仓库地址下的相对地址,可以配置多个,用,分割。 username: xxxxxx # git仓库的账号 password: xxxxx # git仓库的密码 # 客户端调用需要 management: endpoints: web: exposure: include: "*" eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ 复制代码
启动类添加@EnableDiscoveryClient:
@SpringBootApplication @EnableConfigServer @EnableDiscoveryClient public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } } 复制代码
客户端改造
依赖修改:同服务端相同,我们不需要修改,父模块将注册中心等都已经引入(见第一章)
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } } 复制代码
配置文件yml修改:
在前面我们给config-client子模块配置了两个yml文件,一个是传统application.yml一个是bootstrap.yml,bootstrap.yml的启动优先于application.yml
我们修改bootstrap.yml,添加注册中心配置,并将config的配置加上:
- spring.cloud.config.discovery.enabled :开启Config服务发现支持
- spring.cloud.config.discovery.serviceId :指定server端的name,也就是server端spring.application.name的值
- 删除spring.cloud.config.uri
spring: cloud: config: name: spring-cloud-config profile: dev label: master discovery: enabled: true service-id: spring-cloud-config-server eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ 复制代码
随后我们启动三个模块:
- Eureka子模块
- config-server
- config-client
查看Eureka状态 http://localhost:8761/ :
为了达成高可用,我们将config-server的端口号再修改为8770,启动一个新的config-server,这样就有两个config-server同时为我们服务。
调用客户端接口: