srpingboot中refreshContext方法 springboot refresh_客户端


1、前言

说到高可用,在springcloud体系中,是有注册中心的,那么,我们的配置中心也是一个服务,可不可以使用Eureka做服务的注册与发现呢?

答案是肯定的。

2、 Serve端

我们将上一篇的Serve端Copy到新的目录中,增加Eureka-client的依赖,使得Config-Serve可以注册到Eureka上。

2.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>4.0.0org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASEcom.springcloud config-server 0.0.1-SNAPSHOTconfig-serverDemo project for Spring Boot1.8Greenwich.SR1org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-config-server org.springframework.boot spring-boot-starter-test testorg.springframework.cloud spring-cloud-dependencies ${spring-cloud.version}pomimportorg.springframework.boot spring-boot-maven-plugin

2.2 配置文件application.yml

server: port: 8080spring: application: name: spring-cloud-config-server cloud: config: server: git: uri: https://github.com/meteor1993/SpringCloudLearning search-paths: chapter6/springcloud-config username: username password: passwordeureka: client: service-url: defaultZone: http://localhost:8761/eureka/

增加eureka的地址配置

2.3 启动类

启动类增加@EnableEurekaClient激活对注册中心的支持

package com.springcloud.configserver;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.config.server.EnableConfigServer;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication@EnableConfigServer@EnableEurekaClientpublic class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); }}

这样Server注册端我们就修改完成了。先启动Eureka,再启动Serve,在浏览器中访问http://localhost:8761/,就可以看到我们的Serve端已经注册到注册中心了,接下来我们开始改造Client端。

3、 Client端

首先还是将上一篇的Client端Copy过来,和Server端一样,增加Eureka-client的依赖,使得Config-Client可以从注册中心上发现服务。

3.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>4.0.0org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASEcom.springcloud config-client 0.0.1-SNAPSHOTconfig-clientDemo project for Spring Boot1.8Greenwich.SR1org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-config org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-test testorg.springframework.cloud spring-cloud-dependencies ${spring-cloud.version}pomimportorg.springframework.boot spring-boot-maven-plugin

3.2 bootstrap.properties

这里我们需要先清空application.yml,所有的配置全都转移到bootstrap.properties中。

spring.application.name=spring-cloud-config-clientserver.port=8081spring.cloud.config.name=springcloud-configspring.cloud.config.profile=devspring.cloud.config.label=masterspring.cloud.config.discovery.enabled=truespring.cloud.config.discovery.serviceId=spring-cloud-config-servereureka.client.service-url.defaultZone=http://localhost:8761/eureka/

主要是去掉了spring.cloud.config.uri直接指向server端地址的配置,增加了最后的三个配置:

  • spring.cloud.config.discovery.enabled :开启Config服务发现支持
  • spring.cloud.config.discovery.serviceId :指定server端的name,也就是server端spring.application.name的值
  • eureka.client.serviceUrl.defaultZone :指向注册中心的地址

3.3 启动类

启动类增加@EnableEurekaClient激活对注册中心的支持

package com.springcloud.configclient;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication@EnableEurekaClientpublic class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); }}

4. 高可用

现在我们来模拟生产环境。

首先,顺次启动Eureka,Server,Client。

在idea启动两个config-serve,我们修改idea配置启动配置,换到8000端口启动config-serve。

先访问http://localhost:8761/,可以看到两个config-serve都正常注册到注册中心。


srpingboot中refreshContext方法 springboot refresh_xml_02


如上图就可发现会有两个server端同时提供配置中心的服务,防止某一台down掉之后影响整个系统的使用。

我们访问client端的链接:http://localhost:8081/hello, 可以看到页面正常显示:hello dev update1,刷新几次,显示都没问题,现在我们随机停掉一个端口的config-serve服务,再去刷新页面,可以发现,页面依然可以正常显示:hello dev update1。

至此,我们高可用的目的已经达到,但是,不知道各位有没有映像,我们上一篇留了一个坑,服务启动后,我们修改远端github上的配置时,这个配置并不会实时被客户端端所获取到,下面我们来聊一聊有关Spring Cloud Config 刷新的问题。

5、refresh

我们的客户端并不能主动去感知Git或者Svn的配置变化,从而主动获取最新的配置。那么,客户端如何去主动获取新的配置信息呢?springcloud已经给我们提供了解决方案,每个客户端通过POST方法触发各自的/refresh。

修改config-client项目已到达可以refresh的功能。

5.1 添加依赖pom.xml

在我们原有的config-client项目的pom.xml的基础增加新的依赖

org.springframework.boot spring-boot-starter-actuator

增加了spring-boot-starter-actuator包,spring-boot-starter-actuator是一套监控的功能,可以监控程序在运行时状态,其中就包括/refresh的功能。

5.2 开启更新机制

需要给加载变量的类上面加载@RefreshScope,在客户端执行/refresh的时候就会更新此类下面的变量值。

package com.springcloud.configclient.controller;import org.springframework.beans.factory.annotation.Value;import org.springframework.cloud.context.config.annotation.RefreshScope;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * @Author: shiyao.wei * @Date: 2019/7/4 16:19 * @Version: 1.0 * @Desc: */@RestController@RefreshScope // 使用该注解的类,会在接到SpringCloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。public class HelloController { @Value("${springcloud.hello}") private String hello; @RequestMapping("/hello") public String from() { return this.hello; }}

5.3 配置文件bootstrap.properties

spring.application.name=spring-cloud-config-clientserver.port=8081spring.cloud.config.name=springcloud-configspring.cloud.config.profile=devspring.cloud.config.label=masterspring.cloud.config.discovery.enabled=truespring.cloud.config.discovery.serviceId=spring-cloud-config-servereureka.client.service-url.defaultZone=http://localhost:8761/eureka/management.security.enabled=falsemanagement.endpoints.web.exposure.include=*
  • management.security.enabled: springboot 1.5.X 以上默认开通了安全认证,所以需要添加这个配置
  • management.endpoints.web.exposure.include: springboot 2.x 默认只开启了info、health的访问,*代表开启所有访问

5.4 测试

我们先访问客户端的测试连接:http://localhost:8081/hello, 这时,页面的显示是:hello dev update1,我们修改github上的信息,修改为:hello dev update,现在访问http://localhost:8081/hello,得到的信息还是:hello dev update1,现在我们刷新一下客户端,通过cmd命令行执行:curl -X POST http://localhost:8081/actuator/refresh,可以看到命令行上有显示:["springcloud.hello