Spring Cloud第十一篇 | 分布式配置中心高可用
本文是Spring Cloud专栏的第十一篇文章,了解前十篇文章内容有助于更好的理解本文:
一、前言
为了保证配置中心服务的高可用,将配置中心服务端做成一个微服务,将其集群化,从而达到高可用,当你部署了多个Config Server实例并预期一个或多个实例不时不可用时,为确保高可用性,你可以指定多个URL(作为spring.cloud.config.uri属性下的逗号分隔列表),也可以让所有实例在Eureka等Service Registry中注册(如果使用发现优先Bootstrap模式)。注意:只有在Config Server未运行时(即应用程序已退出时)或发生连接超时时,才能确保高可用性,例如:如果Config Server返回500(内部服务器错误)响应或Config Client从Config Server收到401(由于凭据错误或其他原因),则Config Client不会尝试从其他URL获取属性,这种错误表示用户问题而不是可用性问题。
上一篇文章《Spring Cloud第十篇 | 分布式配置中心Config》讲述了一个服务如何从配置中心读取文件,上一篇案例只是通过client直接访问server,地址直接写死,这种方式显然不够灵活,当服务实例很多时,都从配置中心读取文件,如果配置中心服务端地址变动的话,那我们所有的服务都启动不起来了,都需要变更配置中心服务端地址,特别麻烦,由于微服务使用了注册中心,以及注册中心的优点等,我们可以结合Eureka注册中心,将配置中心做成微服务,将其集群化部署,达到配置中心的高可用,架构图如下:
二、改造配置中心服务端
1、添加注册中心客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、主启动类上添加注解@EnableEurekaClient
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}
4、然后启动config server服务端就行了
三、改造配置中心客户端
1、改造步骤同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
2、查看注册中心上注册的服务
3、然后访问http://localhost:8881/index可以看到相同效果,如果需要配置中心高可用,只需要将配置中心启动多个实例就行了。
四、失败快速响应与重试
1、失败快速响应
Spring Cloud Config的客户端会预先加载很多其他信息,然后再开始连接Config Server进行属性的注入。不作任何额外配置的情况下,失败响应有点迟钝,举个简单的例子,关掉config-server,我们直接启动config-client,此时启动会报错,但是报错时间较晚,当我们构建的应用较为复杂的时候,可能在连接Config Server之前花费较长的启动时间,而在一些特殊场景下,我们又希望可以快速知道当前应用是否能顺利地从Config Server获取到配置信息,这对在初期构建调试环境时,可以减少很多等待启动的时间。要实现客户端优先判断Config Server获取是否正常,并快速响应失败内容,只需在Config客户端的bootstrap.yml中配置参数spring.cloud.config.failFast=true即可。
此时不启动config-server直接启动config-client依然会报错,但是我们看到报错时间较早,系统都没打印几条启动日志。
2、重试
上面我们提过了当Config Server宕机或是客户端配置不正确导致连接不到Config Server而启动失败的情况,快速响应的配置可以发挥比较好的效果。但是,如果网络波动等其他间歇性原因导致的问题,直接启动失败似乎代价有些高。所以Config客户端还提供了自动重试的功能,在开启重试功能前,先确保已经配置了(确保开启失败快速响应)spring.cloud.config.failFast=true在进行下面操作。
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>
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
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
五、动态刷新配置
1、有的时候,我动态的更新了Git仓库中的配置文件,那么我如何让我的config-client能够及时感知到呢?方式很简单,首先在config-client中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
由于我们父模块(springcloud-learn)依赖中已经引入该依赖,所以可以省略不引入。
该依赖中包含了/refresh端点的实现,我们将利用这个端点来刷新配置信息。
2、在需要刷新的Bean上添加@RefreshScope注解,不然客户端不知道刷新哪里
3、然后需要在application.yml中配置暴露/refresh端点
management:
endpoints:
web:
exposure:
include: ["info","health","refresh"]
4、然后启动访问http://localhost:8881/index
5、修改码云上的configclient-dev.yml文件,因为我们客户端加载的是这个配置文件
6、然后用postman工具向http://localhost:8881/actuator/refresh地址发送POST请求(该端点只接受post请求,日志上可以看出),结果如下:
7、重新访问http://localhost:8881/index显示内容如下
详细参考案例源码:https://gitee.com/coding-farmer/springcloud-learn
Spring Cloud第十一篇 | 分布式配置中心高可用的更多相关文章
- Spring Cloud第十篇 | 分布式配置中心Config
本文是Spring Cloud专栏的第十篇文章,了解前九篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Clo ...
- Spring Cloud config之一:分布式配置中心入门介绍
Spring Cloud Config为服务端和客户端提供了分布式系统的外部化配置支持.配置服务器为各应用的所有环境提供了一个中心化的外部配置.它实现了对服务端和客户端对Spring Environm ...
- Spring Cloud Config 1 (分布式配置中心)
spring cloud config是spring cloud团队创建的一个全新的项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端和客户端两部分. 服务端也被称为 ...
- Spring Cloud (6) 分布式配置中心-高可用
高可用 现在已经可以从配置中心读取配置文件了,当微服务很多时都从配置中心读取配置文件,这时可以将配置中心做成一个微服务,将其集群化,从而达到高可用. 改造config-server 加入eureka ...
- SpringCloud微服务实战一:Spring Cloud Eureka 服务发现与注册中心(高可用实列为两个注册中心)
微服务架构: 微服务架构的核心思想是,一个应用是由多个小的.相互独立的.微服务组成,这些服务运行在自己的进程中,开发和发布都没有依赖.不同服务通过一些轻量级交互机制来通信,例如 RPC.HTTP 等, ...
- spring cloud 学习(2) - eureka server注册中心高可用及安全认证
接上节继续,注册中心单点肯定是不牢靠的,可以参考下面的方案做成注册中心集群: 弄成3个节点,每个节点向其它节点注册,这样只要集群中有一个节点正常工作即可.为了方便在本机弄出这种效果,我们先修改下hos ...
- 第六篇: 分布式配置中心(Spring Cloud Config)
一.简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件. 在Spring Cloud中,有分布式配置中心组件spring cloud confi ...
- SpringCloud教程 | 第六篇: 分布式配置中心(Spring Cloud Config)
一.简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件.在Spring Cloud中,有分布式配置中心组件spring cloud config ...
- 史上最简单的SpringCloud教程 | 第六篇: 分布式配置中心(Spring Cloud Config)
一.简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件. 在Spring Cloud中,有分布式配置中心组件spring cloud confi ...
随机推荐
- windows 10安装和配置caffe教程 | Install and Configure Caffe on windows 10
本文首发于个人博客https://kezunlin.me/post/1739694c/,欢迎阅读! Install and Configure Caffe on windows 10 Part 1: ...
- 2019-10-16,sudo提权漏洞(CVE-2019-14287)实现
sudo是linux系统命令,让普通账号以root身份执行某些命令,比如,安装软件,查看某些配置文件,关机,重启等,如果普通用户需要使用sudo需要修改配置文件,/etc/sudoers,将sudo使 ...
- 在Kubernetes上运行有状态应用:从StatefulSet到Operator
一开始Kubernetes只是被设计用来运行无状态应用,直到在1.5版本中才添加了StatefulSet控制器用于支持有状态应用,但它直到1.9版本才正式可用.本文将介绍有状态和无状态应用,一个通过K ...
- String s = "a";与String s = new String("a")的区别
String s1 = "a" 时,首先会在字符串常量池中查找有无 “a” 这个对象. 若没找到,就创建一个 "a" 对象, 然后,以 s1 为它的引用.若在字 ...
- 安装软件包的三种方法、RPM包介绍、rpm、yum工具用法、yum搭建本地仓库
第5周第3次课(4月18日) 课程内容: 7.1 安装软件包的三种方法7.2 rpm包介绍7.3 rpm工具用法7.4 yum工具用法7.5 yum搭建本地仓库 7.1 安装软件包的三种方法 rpm工 ...
- window.open()打开新窗口 及参数
在jsp页面中需要使用到弹出窗口,想到js的window对象有一个open方法可以弹出窗口,于是对open方法进行记录. 首先是open方法的语法及定义: 定义: open() 方法用于打开一个新的浏 ...
- ASI的其他使用方法
ASI 除了设置代理监听以外还可以设置block进行监听 如果同时设置block和实现了代理方法 请求过程中 block和代理方法都会调用 一般 代理方法 优先block方法调用 第3种方式调用
- 使用Feign访问接口
添加主要依赖 使用Feign访问接口的配置,如果服务不在Eureka上,可以不加Eureka的依赖,用在FeignClient上指定url的方式访问 dependencies { compile(' ...
- 转:SSL 握手协议详解
SSL 握手协议详解 RSA作为身份认证,ECDHE来交换加密密钥,AES/DES等作为加密. 如果RSA来加解密,那么身份认证后,直接用认证后的RSA公钥解密.不需要再额外交换加密密钥了. 相关报文 ...
- mac 命令记录
1. 安装 mysqlworkbench brew search mysql brew tap caskroom/cask brew cask search mysql brew cask insta ...