SpringCloud之动态刷新、重试、服务化的实现!
假如说我们的配置从远程仓库获取失败了,那么该如何去处理呢?这里就要使用到SpringCloudConfig为我们提的动态刷新重试功能了,SpringCloudConfig是服务化的。那么什么是服务化呢?
服务化
我们在前面的配置中,当ConfigClient需要从ConfigServer上获取配置数据时,我们都是直接在ConfigClient的配置文件中写上ConfigServer的地址,类似下面这种架构:
那么下面我们来演示如何服务化,大家可以根据上一篇的例子进行改造。当然也可以再创建一个项目来实现。这里我选择重新创建来带着大家来搭建。
首先我们依然是创建一个cloudConfig-fwh普通maven工程来作为父工程。然后再从cloudConfig-fwh中创建一个普通的文件夹configRepo来存放github配置文件,然后再分别创建eureka、config_server、config_client。
创建好后,项目结构如下:
那么我们还需要对ConfigClient配置,这里我们在bootstrap.yml中配置,bootstrap.yml优先级比application.yml高,springcloudconfig优先配置都会放在这里:
bootstrap.yml配置如下:
spring: application: name:config-server #本地配置 #profiles: #active:native cloud: config: profile:dev label:master discovery: service-id:config-server3 enabled:true server: port:8002 eureka: client: service-url: defaultZone:http://localhost:7000/eureka/
这里新增的两个配置我说一下,其中discovery.service-id代替了原来的cloud.config.uri
原来的uri需要写很长。而且如果ip地址端口号发生了变化,那么还需要去ConfigServer去修改,这里使用了service-id完美了解决了这个问题。通过service-id去eureka中心寻找ConfigServer的实例。discovery.enabled=true是开启通过eureka来获取ConfigServer。
注意这里有一个小坑。就是这个spring.application.name的名称是你在github仓库的配置文件的前缀如下图:
配置好了后,我们访问http://localhost:8002/love访问结果如下:
动态刷新
接下来我们再来看一下配置文件动态刷新的问题,当Git仓库中配置文件发生改变后,如果我们刷新ConfigServer中的请求地址,会发现数据也跟着变化了,即ConfigServer是能够及时感知到配置文件的变化的,但是这种感知却不能够传递到ConfigClient中去,即ConfigClient是无法及时感知到配置文件的变化的,默认情况下,只有ConfigClient重启,才能够加载到最新的配置文件数据,如何让ConfigClient也能动态刷新配置数据呢?
我们只需要在ConfigClient中加入如下依赖就能动态刷新配置:
org.springframework.boot spring-boot-starter-actuator
添加完成后我们还需要对refresh接口暴露,这里注意,除了G版本的Cloud需要额外手动的暴露refresh接口外,其它版本的Cloud不用配置下面这段配置来进行手动暴露
management: endpoints: web: exposure: include:'refresh'
这里配置好了后,我们对HelloController增加一个注解@RefreshScope当调用refresh接口当时候动态刷新:
@RefreshScope @RestController publicclassHelloController{ @Value("${love}") Stringlove; @GetMapping("/love") publicStringname(){ returnlove; } }
配置好了后,我们重启ConfigClient项目,然后可以看到idea的控制台/actuator/refresh接口已经暴露出来了。
当然配置好了这个动态刷新接口,我们肯定要访问来测试下。接口是否正常。
我们访问http://localhost:8002/actuator/refresh注意这里使用post请求访问,如果如下图一样就说明接口正常:
但细心的人可能这里会发现一个问题,不重启ConfigClient的情况下,也能实现动态刷新配置,但是所有的微服务都要一个个的去发送/actuator/refresh接口请求,很麻烦,那么有什么简便的方式呢?肯定是有的下面我会介绍。
请求失败重试
请求失败了肯定要重试啊,不可能失败了,就让它一直失败。这肯定是不行的。细心的朋友看过我之前的文章的话,我是讲了如何失败重试的,比如网络的波动,当网络质量很差的情况下,就会导致服务调用的失败。那么我们就要做到请求失败了,就要重试。
要实现失败重试也是非常简单的,之前看过我文章的朋友,肯定知道这里需要加两个依赖:
org.springframework.retry spring-retry org.springframework.boot spring-boot-starter-aop
加上这个依赖后,我们需要在ConfigClient的bootstrap.yml中加入如下配置:
fail-fast:true
这个配置的意思是失败快速响应,在默认情况下我们的ConfigClient去访问ConfigServer失败时候,并不会马上报错而是要等到使用到ConfigServer的某个数据的时候才会报错,通俗的意思就是我们之前不是有个love变量吗?如果这个love变量并不存在,而我们的ConfigClient又在调用使用的话,那么就会报错并抛出异常。所以当我们的ConfigClient访问ConfigServer失败的时候,就要开启快速响应,这里可以是失败重试,也可以抛出自定义异常信息。
添加完这个配置之后,为了演示执行效果,接下来我们再做一点点修改,由于目前我们的ConfigServer是有安全认证的,ConfigClient必须要有用户名密码才能访问到ConfigServer中的数据。我们暂时先注释掉ConfigClient中访问ConfigServer的用户名密码,即如下两行:
#spring: #cloud: #config: #username:jishu #password:123456
这里的username和password是在ConfigServer中配置的Security的账户密码信息,这里我们注释掉后,重启ConfigClient项目,我们来看下失败重试的效果:
spring: cloud: config: retry: initial-interval:1000 multiplier:1.1 max-interval:2000
这四个配置解释如下:
- max-attempts表示最大请求次数,默认值为6,就是大家在上图看到的情况
- initial-interval表示请求重试的初始时间间隔
- multiplier表示时间的间隔乘数,由于网络抖动一般都是有规律的,为了防止请求重试时连续的冲突,我们需要一个时间间隔乘数,这里我设置了间隔乘数为1.2,表示第一次重试间隔时间为1s,第二次间隔时间为1.2秒,第三次间隔时间为1.44秒…
- max-interval表示重试的最大间隔时间
开启了请求重试机制之后,即使在弱网环境下,我们也能有效保证服务的可用性。
总结
本文主要向大家介绍了分布式配置中心SpringCloudConfig中三个常见的问题,服务化、配置数据动态刷新以及请求失败重试。服务化降低了ConfigServer和ConfigClient之间的耦合度,使我们的项目架构更加规范;动态刷新则让我们在不重启ConfigClient的情况下,能够刷新配置数据;最后的请求重试则保证了弱网环境下服务的可用性,在实际生产项目中,这三个基本上也都是必配的,大家需要认真掌握。
项目地址
github
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。