Spring Cloud快速开发入门第十一篇---分布式配置中心高可用

本文是Spring Cloud专栏的第十一篇文章,了解前十篇文章内容有助于更好的理解本文:

  1. Spring Cloud快速开发入门第一篇---SpringCloud前言及其常用组件介绍概览
  2. Spring Cloud快速开发入门第二篇---使用并认识Eureka注册中心
  3. Spring Cloud快速开发入门第三篇---搭建高可用Eureka注册中心
  4. Spring Cloud快速开发入门第四篇---客户端负载均衡Ribbon
  5. Spring Cloud快速开发入门第五篇---服务熔断Hystrix
  6. Spring Cloud快速开发入门第六篇---Hystrix仪表盘监控Hystrix Dashboard
  7. Spring Cloud快速开发入门第七篇---声明式服务调用Feign
  8. Spring Cloud快速开发入门第八篇---Hystrix集群监控Turbine
  9. Spring Cloud快速开发入门第九篇---分布式服务跟踪Sleuth
  10. Spring Cloud快速开发入门第十篇---分布式配置中心Config

当你部署了多个Config Server实例并预期一个或多个实例不时不可用时,为确保高可用性,你可以指定多个URL(作为spring.cloud.config.uri属性下的逗号分隔列表),也可以让所有实例在Eureka等Service Registry中注册(如果使用发现优先Bootstrap模式)。请注意,只有在Config Server未运行时(即应用程序已退出时)或发生连接超时时,才能确保高可用性,例如,如果Config Server返回500(内部服务器错误)响应或Config Client从Config Server收到401(由于凭据错误或其他原因),则Config Client不会尝试从其他URL获取属性,这种错误表示用户问题而不是可用性问题。

如果在Config Server上使用HTTP基本安全性,则仅当你在spring.cloud.config.uri属性下指定的每个URL中嵌入凭据时,才能支持每个Config Server身份验证凭据,如果使用任何其他类型的安全机制,则无法(目前)支持每个Config Server身份验证和授权。

上一篇文章讲述了一个服务如何从配置中心读取文件,上一篇案例只是通过client直接访问server,地址直接写死,这种方式显然不够灵活,当服务实例很多时,都从配置中心读取文件,如果配置配置中心服务端宕机,那我们所有的服务都启动不起来了,由于微服务使用了注册中心,以及注册中心的优点等,我们可以结合Eureka注册中心,将配置中心做成微服务,将其集群化部署,达到配置中心的高可用,架构图如下:

å¨è¿éæå¥å¾çæè¿°

 

一、改造配置中心服务端

1-1、添加注册中心客户端依赖

<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

1-2、主启动类上添加注解@EnableEurekaClient

1-3、在application.yml文件中添加Eureka相关配置

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8700/eureka
    #客户端每隔30秒从Eureka服务上更新一次服务信息
    registry-fetch-interval-seconds: 30
    #需要将我的服务注册到eureka上
    register-with-eureka: true
    #需要检索服务
    fetch-registry: true
  #心跳检测检测与续约时间
  instance:
    #告诉服务端,如果我10s之内没有给你发心跳,就代表我故障了,将我剔除掉,默认90s
    #Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则剔除(客户端告诉服务端按照此规则等待自己)
    lease-expiration-duration-in-seconds: 10
    #每隔2s向服务端发送一次心跳,证明自已依然活着,默认30s
    #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(客户端告诉服务端自己会按照该规则)
    lease-renewal-interval-in-seconds: 2
    # 启用ip配置 这样在注册中心列表中看见的是以ip+端口呈现的
    prefer-ip-address: true
    # 实例名称  最后呈现地址:ip:2002
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

然后启动config server服务端就行了

二、改造配置中心客户端

改造步骤同1-1,1-2,1-3,然后在application.yml文件中将spring.cloud.config修改为如下样子:

spring:
  cloud:
    config:
      #uri则表示配置中心的地址
      #uri: http://localhost:8888
      #注:config 客户端在没有 spring.cloud.config.name属性的时候,服务端{application} 获取的是客户端
      #spring.application.name的值,否则,获取的是 spring.cloud.config.name的值。
      #1)、当没有spring.cloud.config.name时,客户端获取的是spring.application.name 所对应的git库中的文件,并且只能
      #获取一个文件,
      #2)、当一个项目中有需求要获取多个文件时,就需要用到spring.cloud.config.name这个属性,以逗号分割
      name: configclient
      profile: dev
      #label对应了label部分
      label: master
      discovery:
        #表示开启通过服务名来访问config-server
        enabled: true
        #则表示config-server的服务名
        service-id: tmgsp-config-server

查看注册中心上注册的服务

然后访问http://localhost:8881/index可以看到相同效果,如果需要配置中心高可用,只需要将配置中心启动多个实例就行了。

三、失败快速响应与重试

3-1、失败快速响应

Spring Cloud Config的客户端会预先加载很多其他信息,然后再开始连接 Config Server 进行属性的注入。不作任何额外配置的情况下,失败响应有点迟钝,举个简单的例子,关掉config-server,我们直接启动config-client,此时启动会报错,但是报错时间较晚,当我们构建的应用较为复杂的时候,可能在连接 Config Server之前花费 较长的启动时间,而在一些特殊场景下,我们又希望可以快速知道当前应用是否能顺利地从 Config Server获取到配置信息,这对在初期构建调试环境时,可以减少很多等待启动的时间。要实现客户端优先判断 Config Server获取是否正常,并快速响应失败内容,

只需在 客户端的bootstrap.yml中配置参数 spring.cloud.config.failFast=true即可。

此时不启动config-server直接启动config-client依然会报错,但是我们看到报错时间较早,系统都没打印几条启动日志。

3-2、重试

上面我们提过了当Config Server宕机或是客户端配置不正确导致连接不到Config Server而启动失败的情况,快速响应的配置可以发挥比较好的效果。但是,是以为网络波动等其他间歇性原因导致的问题,直接启动失败似乎代价有些高。所以,Config客户端还提供了自动重试的功能,在开启重试功能前,先确保已经配置了(确保开启失败快速响应)spring.cloud.config.failFast=true在进行下面操作

3-2-1、在客户端添加依赖

		<!--连接config-server重试机制相关依赖-->
		<dependency>
			<groupId>org.springframework.retry</groupId>
			<artifactId>spring-retry</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

 3-2-2、不需要再做其他任何配置,启动客户端应用,在控制台中可以看到如下内容。客户 端在连接 Config Server失败之后,会继续尝试,直到第6次失败后,才返回错误信息。通过这样的重试机制,可以避免一些间歇性问题引起的失败导致客户端应用无 法启动的情况。查看日志如下,测试的时候切记config server需要在注册中心没有剔除掉,要是剔除掉那就没的说了。

INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://172.20.10.2:8888/
INFO 9996 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SPRINGCLOUD-CONFIG-CLIENT/172.20.10.2:8881 - Re-registering apps/SPRINGCLOUD-CONFIG-CLIENT
INFO 9996 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SPRINGCLOUD-CONFIG-CLIENT/172.20.10.2:8881: registering service...
INFO 9996 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SPRINGCLOUD-CONFIG-CLIENT/172.20.10.2:8881 - registration status: 204
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://172.20.10.2:8888/. Will be trying the next url if available
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://172.20.10.2:8888/
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://172.20.10.2:8888/. Will be trying the next url if available
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://172.20.10.2:8888/
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://172.20.10.2:8888/. Will be trying the next url if available
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://172.20.10.2:8888/
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://172.20.10.2:8888/. Will be trying the next url if available
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://172.20.10.2:8888/
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://172.20.10.2:8888/. Will be trying the next url if available
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://172.20.10.2:8888/
INFO 9996 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://172.20.10.2:8888/. Will be trying the next url if available
ERROR 9996 --- [           main] o.s.boot.SpringApplication               : Application run failed

 3-2-3、从日志上可以看出,config client一共尝试了六次去访问config server,六次都失败了才抛异常和重试机制相关的配置有如下四个:

# 配置重试次数,默认为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=2000

四、动态刷新配置

4-1、有的时候,我动态的更新了Git仓库中的配置文件,那么我如何让我的config-client能够及时感知到呢?方式很简单,首先在config-client中添加如下依赖:

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

由于我们父模块(springcloud-learn)依赖中已经引入该依赖,所以可以省略不引入。

该依赖中包含了/refresh端点的实现,我们将利用这个端点来刷新配置信息。

4-2、在需要刷新的Bean上添加@RefreshScope注解,不然客户端不知道刷新哪里

4-3、然后需要在application.yml中配置暴露/refresh端点

management:
  endpoints:
    web:
      exposure:
        include: ["info","health","refresh"]

4-4、然后启动访问

4-5、修改码云上的configclient-dev.yml文件,因为我们客户端加载的是这个配置文件

4-6、然后用postman工具向http://localhost:8881/actuator/refresh地址发送POST请求(该端点只接受post请求,日志上可以看出),结果如下:

4-7、重新访问http://localhost:8881/index显示内容如下

显示更新刷新成功,也可以去查看日志,去仓库拉取配置了

 

 

 

spring3-2.cloud.config.fail-fast=true

参考:Spring Cloud 参考文档(Spring Cloud Config Client)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值