SpringCloud之动态刷新、重试、服务化的实现

假如说我们的配置从远程仓库获取失败了,那么该如何去处理呢?这里就要使用到 Spring Cloud Config 为我们提的动态刷新重试功能了,Spring Cloud Config 是服务化的。那么什么是服务化呢?

服务化

我们在前面的配置中,当 Config Client 需要从 Config Server 上获取配置数据时,我们都是直接在 Config Client 的配置文件中写上 Config Server 的地址,类似下面这种架构:

这种写法相当于将 Config Client 和 Config Server 绑定死了,以后 Config Server 的地址不能变,Config Server 也不能挂,否则 Config Client 就获取不到信息了,而且这种方式也破坏了我们微服务的整体架构,即服务之间互相调用,获取对方的信息都是去服务注册中心上获取,所以我们要对这种结构进行改造,改造成下面这种结构:

当 Config Server 启动时,将自己注册到服务注册中心 Eureka 上,所有 Config Client 都从 Eureka 上去获取 Config Server 的信息,这样我们就成功将 Config Server 和 Config Client 解耦了,Eureka 在这里依然扮演了数据中心的角色。

那么下面我们来演示如何服务化,大家可以根据上一篇的例子进行改造。当然也可以再创建一个项目来实现。这里我选择重新创建来带着大家来搭建。

首先我们依然是创建一个cloudConfig-fwh普通maven工程来作为父工程。然后再从cloudConfig-fwh中创建一个普通的文件夹configRepo来存放github配置文件,然后再分别创建eureka、config_server、config_client。

创建好后,项目结构如下:

然后我们分别将config_client 和 config_server 注册到eureka实例上。

我们访问localhost:7000 发现已经注册上去了。

那么我们还需要对Config Client配置,这里我们在bootstrap.yml中配置,bootstrap.yml优先级比application.yml高,spring cloud config 优先配置都会放在这里:
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地址端口号发生了变化,那么还需要去Config Server去修改,这里使用了service-id完美了解决了这个问题。通过service-id去eureka中心寻找Config Server的实例。discovery.enabled=true 是开启通过eureka来获取Config Server。

注意这里有一个小坑。就是这个spring.application.name的名称是你在github仓库的配置文件的前缀如下图:

这里取config-server就可以了。

配置好了后,我们访问http://localhost:8002/love 访问结果如下:

这样就访问成功了,说明我们的配置没有问题。下面我们来说一下动态刷新。

动态刷新

接下来我们再来看一下配置文件动态刷新的问题,当 Git 仓库中配置文件发生改变后,如果我们刷新 Config Server 中的请求地址,会发现数据也跟着变化了,即 Config Server 是能够及时感知到配置文件的变化的,但是这种感知却不能够传递到 Config Client 中去,即 Config Client 是无法及时感知到配置文件的变化的,默认情况下,只有 Config Client 重启,才能够加载到最新的配置文件数据,如何让 Config Client 也能动态刷新配置数据呢?

我们只需要在Config Client 中加入如下依赖就能动态刷新配置:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

添加完成后我们还需要对refresh接口暴露,这里注意,除了G版本的Cloud需要额外手动的暴露refresh接口外,其它版本的Cloud不用配置下面这段配置来进行手动暴露

management:
 endpoints:
  web:
   exposure:
    include: 'refresh'

这里配置好了后,我们对HelloController增加一个注解@RefreshScope 当调用refresh 接口当时候动态刷新:

@RefreshScope
@RestController
public class HelloController {
  @Value("${love}")
  String love;

  @GetMapping("/love")
  public String name() {
    return love;
  }
}

配置好了后,我们重启Config Client项目,然后可以看到idea的控制台/actuator/refresh接口已经暴露出来了。

这个接口用来动态刷新配置文件。

当然配置好了这个动态刷新接口,我们肯定要访问来测试下。接口是否正常。
我们访问http://localhost:8002/actuator/refresh 注意这里使用post请求访问,如果如下图一样就说明接口正常:

但细心的人可能这里会发现一个问题,不重启Config Client的情况下,也能实现动态刷新配置,但是所有的微服务都要一个个的去发送/actuator/refresh 接口请求,很麻烦,那么有什么简便的方式呢?肯定是有的下面我会介绍。

请求失败重试

请求失败了肯定要重试啊,不可能失败了,就让它一直失败。这肯定是不行的。细心的朋友看过我之前的文章的话,我是讲了如何失败重试的,比如网络的波动,当网络质量很差的情况下,就会导致服务调用的失败。那么我们就要做到请求失败了,就要重试。

要实现失败重试也是非常简单的,之前看过我文章的朋友,肯定知道这里需要加两个依赖:

<dependency>
  <groupId>org.springframework.retry</groupId>
  <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

加上这个依赖后,我们需要在Config Client 的bootstrap.yml中加入如下配置:

fail-fast: true

这个配置的意思是失败快速响应,在默认情况下 我们的Config Client 去访问Config Server 失败时候,并不会马上报错 而是要等到使用到Config Server 的某个数据的时候才会报错,通俗的意思就是我们之前不是有个love变量吗?如果这个love变量并不存在,而我们的Config Client又在调用使用的话,那么就会报错并抛出异常。所以当我们的Config Client 访问 Config Server 失败的时候,就要开启快速响应,这里可以是失败重试,也可以抛出自定义异常信息。

添加完这个配置之后,为了演示执行效果,接下来我们再做一点点修改,由于目前我们的 Config Server 是有安全认证的,Config Client 必须要有用户名密码才能访问到 Config Server 中的数据。我们暂时先注释掉 Config Client 中访问 Config Server 的用户名密码,即如下两行:

#spring:
# cloud:
#  config:
#   username: jishu
#   password: 123456

这里的username 和 password 是在Config Server 中配置的Security的账户密码信息,这里我们注释掉后,重启Config Client 项目,我们来看下失败重试的效果:

可以看到,一共发了6次请求,第一失败后,还继续重试了5次,这就是默认的请求策略,我们可以配置请求策略:

spring:
 cloud:
  config:
   retry:
    initial-interval: 1000
    multiplier: 1.1
    max-interval: 2000

这四个配置解释如下:

  • max-attempts 表示最大请求次数,默认值为 6 ,就是大家在上图看到的情况
  • initial-interval 表示请求重试的初始时间间隔
  • multiplier 表示时间的间隔乘数,由于网络抖动一般都是有规律的,为了防止请求重试时连续的冲突,我们需要一个时间间隔乘数,这里我设置了间隔乘数为 1.2 ,表示第一次重试间隔时间为 1 s,第二次间隔时间为 1.2 秒,第三次间隔时间为 1.44 秒…
  • max-interval 表示重试的最大间隔时间

开启了请求重试机制之后,即使在弱网环境下,我们也能有效保证服务的可用性。

总结

本文主要向大家介绍了分布式配置中心 Spring Cloud Config 中三个常见的问题,服务化、配置数据动态刷新以及请求失败重试。服务化降低了 Config Server 和 Config Client 之间的耦合度,使我们的项目架构更加规范;动态刷新则让我们在不重启 Config Client 的情况下,能够刷新配置数据;最后的请求重试则保证了弱网环境下服务的可用性,在实际生产项目中,这三个基本上也都是必配的,大家需要认真掌握。

项目地址

github

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • SpringCloud重试机制配置详解

    首先声明一点,这里的重试并不是报错以后的重试,而是负载均衡客户端发现远程请求实例不可到达后,去重试其他实例. @Bean @LoadBalanced RestTemplate restTemplate() { HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); httpRequestFactory.setReadTimeout(5000)

  • Spring Cloud 动态刷新配置信息教程详解

    有时候在配置中心有些参数是需要修改的,这时候如何不重启而达到实时生效的效果呢? 添加依赖 <dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ... </dependencies>

  • SpringCloud之动态刷新、重试、服务化的实现

    假如说我们的配置从远程仓库获取失败了,那么该如何去处理呢?这里就要使用到 Spring Cloud Config 为我们提的动态刷新重试功能了,Spring Cloud Config 是服务化的.那么什么是服务化呢? 服务化 我们在前面的配置中,当 Config Client 需要从 Config Server 上获取配置数据时,我们都是直接在 Config Client 的配置文件中写上 Config Server 的地址,类似下面这种架构: 这种写法相当于将 Config Client 和

  • Springcloud Bus消息总线原理是实现详解

    目录 springcloud Bus 什么是springcloud Bus 什么是消息总线 Bus实现自动刷新的原理 RabbitMQ的下载配置 Erlang RabbitMQ Bus动态刷新 全局广播通知代码实现 定点通知代码实现 springcloud Bus 什么是springcloud Bus   上一章的springcloud Bus是对分布式微服务的远程配置,但是有一个遗留的问题就是,Config客户端对远程配置的刷新需要手动使用post请求来完成,这就使得Config客户端动态刷新

  • 解决启用 Spring-Cloud-OpenFeign 配置可刷新项目无法启动的问题

    本篇文章涉及底层设计以及原理,以及问题定位,比较深入,篇幅较长,所以拆分成上下两篇: 上:问题简单描述以及 Spring Cloud RefreshScope 的原理 下:当前 spring-cloud-openfeign + spring-cloud-sleuth 带来的 bug 以及如何修复 最近在项目中想实现 OpenFeign 的配置可以动态刷新(主要是 Feign 的 Options 配置),例如: feign: client: config: default: # 链接超时 conn

  • SpringCloud Config统一配置中心问题分析解决与客户端动态刷新实现

    目录 一.问题分析及解决方案 1.问题分析 2.解决方案 二.手动刷新 1.添加服务监控 2.暴露服务端点 3.刷新业务类controller 4.手动刷新 三.自动刷新 什么是总线 基本原理 一.问题分析及解决方案 1.问题分析 上一章我们讲过远程仓储统一管理配置信息,客户端可以通过统一配置服务中心 config server 服务端获取配置信息.现在我们来做一个改变,并进行分析. 首先启动注册中心.统一配置中心configserver服务端.订单服务.浏览器访问地址:http://local

  • springcloud之Feign、ribbon如何设置超时时间和重试机制

    Feign.ribbon设置超时时间和重试机制 前言 我们在微服务调用服务的时候,会使用feign和ribbon,比如有一个实例发生了故障而该情况还没有被服务治理机制及时的发现和摘除,这时候客户端访问该节点的时候自然会失败. 所以,为了构建更为健壮的应用系统,我们希望当请求失败的时候能够有一定策略的重试机制,而不是直接返回失败. 先看一个配置: #预加载配置,默认为懒加载 ribbon: eager-load: enabled: true clients: zoo-plus-email zoo-

  • 详解Spring Cloud Zuul重试机制探秘

    简介 本文章对应spring cloud的版本为(Dalston.SR4),具体内容如下: 开启Zuul功能 通过源码了解Zuul的一次转发 怎么开启zuul的重试机制 Edgware.RC1版本的优化 开启Zuul的功能 首先如何使用spring cloud zuul完成路由转发的功能,这个问题很简单,只需要进行如下准备工作即可: 注册中心(Eureka Server) zuul(同时也是Eureka Client) 应用服务(同时也是Eureka Client) 我们希望zuul和后端的应用

  • Spring Cloud重试机制与各组件的重试总结

    SpringCloud重试机制配置 首先声明一点,这里的重试并不是报错以后的重试,而是负载均衡客户端发现远程请求实例不可到达后,去重试其他实例. @Bean @LoadBalanced RestTemplate restTemplate() { HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); httpRequestFactory.se

  • SpringCloud之分布式配置中心Spring Cloud Config高可用配置实例代码

    一.简介 当要将配置中心部署到生产环境中时,与服务注册中心一样,我们也希望它是一个高可用的应用.Spring Cloud Config实现服务端的高可用非常简单,主要有以下两种方式. 传统模式:不需要为这些服务端做任何额外的配置,只需要遵守一个配置规则,将所有的Config Server都指向同一个Git仓库,这样所有的配置内容就通过统一的共享文件系统来维护.而客户端在指定Config Server位置时,只需要配置Config Server上层的负载均衡设备地址即可, 就如下图所示的结构. 服

  • springcloud Zuul动态路由的实现

    前言 Zuul 是Netflix 提供的一个开源组件,致力于在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架.也有很多公司使用它来作为网关的重要组成部分,碰巧今年公司的架构组决定自研一个网关产品,集动态路由,动态权限,限流配额等功能为一体,为其他部门的项目提供统一的外网调用管理,最终形成产品(这方面阿里其实已经有成熟的网关产品了,但是不太适用于个性化的配置,也没有集成权限和限流降级). 不过这里并不想介绍整个网关的架构,而是想着重于讨论其中的一个关键点,并且也是经常在交流群中听人说起的:

随机推荐