白话SpringCloud | 第七章:分布式配置中心的使用
前言
介绍完服务的容错保护处理,接下来我们来了解下关于分布式配置中心的相关知识和使用。众所周知,随着项目的越来越多,日益庞大,每个子项目都会伴随着不同的配置项,于此也就多了很多的配置文件。倘若某些配置信息修改,可能就会伴随着一系列配置文件的更新和相应服务的重启操作了。这对于实施而言,也是噩梦一般的存在,增加了一系列运维成本,也会无形中提高出错的机率。所以在微服务越来越多时,就会引入今天要讲解的分布式配置中心,它就是来解决此类问题的。话不多说,开始吧~
一点知识
为什么要统一管理微服务配置
在写这篇文章之前,在公众号里有推送了一篇《为什么需要分布式配置中心》的文章。里面也大致说明了,大家可以看一看。简单来说,就是随着业务的发展、微服务架构的升级,服务的数量、程序的配置日益增多(各种微服务、各种服务器地址、各种参数),传统的配置文件方式和数据库的方式已无法满足开发人员对配置管理的要求,即
安全性:配置跟随源代码保存在代码库中,容易造成配置泄漏;
时效性:修改配置,需要重启服务才能生效;
局限性:无法支持动态调整:例如日志开关、功能开关;
其实说白了,就是当业务需求有变更时,可以通过修改配置文件或者参数的形式,能够自动更新配置。减少不必要的重启服务的操作。正常情况下,一般的业务系统都有个参数配置表的,里面记录着不同业务参数,以此来应对不同的需求场景,也就是需求口中常说的:要能灵活配置。
而在微服务中,由于每个微服务都是独立的数据库,传统的配置无法满足了。所以才出现了分布式配置中心服务,专门来解决此类问题的。
在微服务架构中,微服务的统一配置管理一般有以下需求:
- 集中管理配置:一个使用微服务架构的应用系统可能会包括成千上万个微服务,因此集中管理配置是非常有必要的。
- 不同环境不同配置:数据源配置在不同的环境(开发、测试、预发布、生产等)中是不同的。
- 运行期间可动态调整:可根据各个微服务的负载情况,动态调整数据源连接池大小或熔断阈值,并且在调整配置时不重启微服务。
- 配置修改后自动更新:如配置内容发生变化,微服务能够自动更新配置。
综上所述,对于微服务架构而言,一个通用的配置管理机制必不可少,常见做法是使用配置服务器管理配置。目前市面上开源的配置中心有很多,如
- Apollo(阿波罗):携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
- Qconf:一个分布式配置管理工具,360出品。
- Disconf:专注于各种「分布式系统配置管理」的「通用组件」和「通用平台」, 提供统一的「配置管理服务」。
具体的可以看看之前说的文章《为什么需要分布式配置中心》,这里就不过多阐述了。
Spring-Cloud-config实践
何为SpringCloudConfig
Spring Cloud Config
为分布式系统外部化配置提供了服务端和客户端的支持,它包括Config Server
和Config Client
两部分。目前支持git
、svn
、vault
、jdbc
和本地
几种存储方式。
最常用的存储方式就是git
了。
简单来说,各客户端程序通过访问服务端获取相应的配置信息。接下来我们看看下面这张图
- 远程Git仓库:存储配置文件。
- ConfigServer:分布式配置管理中心,会于维护自己的git仓库信息。
- 本地Git仓库:在ConfigServer中,每次客户端请求获取配置信息时,都会从git仓库获取最新的配置到本地,然后本地读取并返回,远程无法获取时,使用本地仓库信息。
从上图可以看出,Config Server
巧妙地通过git clone
将配置信息存于本地,起到了缓存的作用,即使当Git
服务端无法访问的时候,依然可以取Config Server
中的缓存内容进行使用。
这里以git为例,做个简单示例。
首先,在github中创建一个目录:spring-cloud-config-repo
,来存放配置文件信息。
my-config-client-dev.properties
config=this is dev!
my-config-client-dev.properties
config=this is test!
注意:因为存在多个项目都是用配置中心问题,而每个项目的应用名称是不尽相同的,所以配置文件的命名方式即为:
应用名
+环境变量(profile)
的命名方式。因此,每个应用理应设置应用名称,是个好习惯。具体的映射规则,在Server端
会进行说明的。
Server端
创建工程:spring-cloud-confg-server
0.引入pom依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
1.启动类加入@EnableConfigServer注解,声明是ConfigServer
。
@SpringBootApplication
@EnableConfigServer
@Slf4j
public class SpringCloudConfigServerApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringCloudConfigServerApplication.class, args);
log.info("spring-cloud-config-server启动!");
}
}
2.配置文件,添加git仓库相关信息。
spring.application.name=spring-cloud-config-server
server.port=5678
#配置文件git配置
spring.cloud.config.server.git.uri=https://github.com/xie19900123/spring-cloud-learning.git
# 搜索路径,即配置文件的目录,可配置多个,逗号分隔。默认为根目录。
spring.cloud.config.server.git.searchPaths=spring-cloud-config-repo
# git用户名和密码 针对私有仓库而言需要填写
spring.cloud.config.server.git.username=
spring.cloud.config.server.git.password=
3.启动应用,访问http://127.0.0.1:5678/my-config-client-dev.properties ,返回了配置文件的信息,说明已经读取到远程仓库信息了。
我们可以通过访问配置信息的URL与配置文件的映射关系,获取相应的配置信息。
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
url会映射{application}-{profile}.properties对应的配置文件,
其中{label}对应Git上不同的分支,默认为master。我们可以尝试构造不同的url来访问不同的配置内容,
比如:
要访问master
分支,my-config-client
应用的dev环境
http://127.0.0.1:5678/my-config-client/dev/master
返回的信息:
{
"name": "my-config-client",
"profiles": ["dev"],
"label": "master",
"version": "51d81a5aacce45b97af6db2482769fe02873c548",
"state": null,
"propertySources": [{
"name": "https://github.com/xie19900123/spring-cloud-learning.git/spring-cloud-config-repo/my-config-client-dev.properties",
"source": {
"config": "this is dev!"
}
}]
}
此时,查看控制台,可以获悉本地也保存着一份配置信息。
2018-10-09 23:32:46.833 INFO 988 --- [nio-5678-exec-2] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/Users/xiede/AppData/Local/Temp/config-repo-7233984840222622045/spring-cloud-config-repo/my-config-client-dev.properties
2018-10-09 23:32:46.834 INFO 988 --- [nio-5678-exec-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@66e76432: startup date [Tue Oct 09 23:32:46 CST 2018]; root of context hierarchy
查看本地仓库目录:
此时,修改远程的配置文件,再次访问可以看见返回的参数是最新修改后的参数值了,大家可以自行试试。
Client端
创建一个客户端:spring-cloud-confg-client
。当然也可以改造原来的应用了,只需加入相应pom文件和配置文件即可。
0.加入pom依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
1.创建启动类,就是一个正常的web应用。
/**
* Spring Cloud Config client 示例
* @author oKong
*
*/
@SpringBootApplication
@Slf4j
public class SpringCloudConfigClientApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringCloudConfigClientApplication.class, args);
log.info("spring-cloud-config-client启动!");
}
}
2.配置文件添加:bootstrap.properties
和常规的application.properties
。
bootstrap.properties
# 设置分支
spring.cloud.config.label=master
# 环境变量
spring.cloud.config.profile=dev
# 是否使用注册中心方式进行获取 后续会进行讲解
#spring.cloud.config.discovery.enabled=false
# 服务端地址
# 在不使用注册中心模式下 直接填写实际地址
spring.cloud.config.uri=http://127.0.0.1:5678
# 注册中心应用id 下一章节会进行讲解
#spring.cloud.config.discovery.service-id=
application.properties
# 设置应用名称,需要和配置文件匹配
spring.application.name=my-config-client
server.port=5666
这里需要注意:
spring-cloud-config
相关的属性必须配置在bootstrap.properties
中,config部分内容才能被正确加载。因为config的相关配置会先于application.properties
,而bootstrap.properties
的加载也是先于application.properties
。
3.编写一个控制层,利用@Value
进行参数测试。
/**
* config client 简单示例
* @author oKong
*
*/
@RestController
public class DemoController {
@Value("${config}")
String config;
@GetMapping("/")
public String demo() {
return "返回的config参数值为:" + config;
}
}
4.启动应用,访问:http://127.0.0.1:5666/ ,可以看见配置信息已经被正确返回了。
自此,一个简单的配置中心示例就结束了。
目前为止,我们还没有手动去修改远程的配置文件参数值,可以试试,在修改后,客户端去返回相应的参数值,会发现还是旧的,并没有进行更新操作。因为配置文件是是在应用启动的时候进行加载的,而且远程仓库修改了配置文件,客户端并不知道已经修改了,不会发起请求的。关于配置参数自动更新相关知识点,会在下一章节进行讲解的。
参考资料
总结
本章节主要讲解了常规操作下,如何使用
SpringCloudConfig
进行统一参数配置管理。针对配置动态刷新,实时生效相关知识点,会在下一章节进行单独讲解的,本章节先让大家有个直观的认识,了解下SpringCloudConfig
实现的一些机制。本文仅仅是讲解了git
示例,有兴趣的同学可以试试其他的,比如svn
或者本地资源库
等形式。都是类似配置,就不加以说明了。
最后
目前互联网上大佬都有分享
SpringCloud
系列教程,内容可能会类似,望多多包涵了。原创不易,码字不易,还希望大家多多支持。若文中有错误之处,还望提出,谢谢。
老生常谈
- 个人QQ:
499452441
- 微信公众号:
lqdevOps
个人博客:http://blog.lqdev.cn
源码示例:https://github.com/xie19900123/spring-cloud-learning
白话SpringCloud | 第七章:分布式配置中心的使用的更多相关文章
- 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新
前言 上一章节,简单介绍了分布式配置中心Spring Cloud Config的使用.同时,我们也遗漏了一些问题,比如如何配置实时生效,当服务端地址变更或者集群部署时,如何指定服务端地址?回想,在服务 ...
- SpringCloud(6)分布式配置中心Spring Cloud Config
1.Spring Cloud Config 简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件.在Spring Cloud中,有分布式配置中心组 ...
- Springcloud 2.x 版本 分布式配置中心
一.什么是分布式配置中心? 就是为微服务架构中的微服务提供集中化的外部配置支持,配置中心为各个微服务应用的所有环境提供了中心化的外部配置(可能比较难理解,想知道是什么意思就要知道为什么这么配置:这么配 ...
- SpringCloud使用Consul作为分布式配置中心
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_36027670/article/de ...
- SpringCloud学习之Config分布式配置中心(八)
统一配置中心概述 如果微服务架构中没有使用统一配置中心时,所存在的问题: 配置文件分散在各个项目里,不方便维护 配置内容安全与权限,实际开发中,开发人员是不知道线上环境的配置的 更新配置后,项目需要重 ...
- 一起来学Spring Cloud | 第七章:分布式配置中心(Spring Cloud Config)
上一章节,我们讲解了服务网关zuul,本章节我们从git和本地两种存储配置信息的方式来讲解springcloud的分布式配置中心-Spring Cloud Config. 一.Spring Cloud ...
- SpringCloud全家桶学习之分布式配置中心----Config(七)
一.概述 (1)背景 微服务意味着将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中出现大量的服务.由于每个服务都需要配置必要的配置信息才能运行,所以一套集中式的.动态的配置管理 ...
- SpringCloud教程 | 第六篇: 分布式配置中心(Spring Cloud Config)(Finchley版本)
在上一篇文章讲述zuul的时候,已经提到过,使用配置服务来保存各个服务的配置文件.它就是Spring Cloud Config. 一.简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管 ...
- springcloud 高可用分布式配置中心
SpringCloud教程七:高可用的分布式配置中心(SpringCloud Config) 当服务有很多 都要从服务中心获取配置时 这是可以将服务中心分布式处理 是系统具备在集群下的大数据处理 主要 ...
随机推荐
- Stopwatch运行时间 Parallel并行任务
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...
- MongoVue 破解治标不治本
MongoVue 破解治标不治本 ---------解决燃眉之急 注册表中查找B1159E65-821C3-21C5-CE21-34A484D54444中的子项4FF78130 ,删除其下的三个子项 ...
- c++缓冲区------c++ Primer Plus
通常,通过使用缓冲区可以更高效地处理输入和输出.缓冲区是用作中介的内存块,它是将信息从设备传输到程序或从程序传输给设备的临时存储工具.通常,像硬盘驱动器这样的设备以512字节(或更多)的块为单位来传输 ...
- fputs()
原型:int fputs(const char *str, FILE *stream) 参数解释: const char *str : const限制函数内部修改指针指向的数据(在函数形参使用cons ...
- 美团Java实习面试经历(拿到Offer)
美团我是在拉勾网上投的简历,之前也投过一次,简历都没通过删选,后来让学姐帮我改了一下简历,重新投另一个部门,获得了面试机会.10月23日中午HR打电话过来预约了下午4点半面试,说会在线写代码,让我 ...
- kali linux之本地提权
已实现本地低权限帐号登录,希望获取更高权限,实现对目标进一步控制 系统帐号之间权限隔离(操作系统安全的基础,用户空间,内核空间) 系统帐号(用户帐号登录时获取权限令牌,服务帐号无需用户登录已在后台启动 ...
- oracle闪回存储过程
源地址:https://www.baidu.com/link?url=qgVCi_BLGOYqxJN0Fqqt-9N0SmCwtGI70SIh-TFpx1nP6oaVoMj8H6yjEqilto6TM ...
- Kafka,Mq,Redis作为消息队列有何差异?
Kafka作为新一代的消息系统,mq是比较成熟消息系统,而redis也可以发布订阅,那么这三者有何异同? RabbitMQ 是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,X ...
- linux下蓝牙开发(bluez应用)
编译blueZ-5.25 需要先编译安装以下包: bluez-libs-3.36.tar.gz expat-2.1.0.tar.gz dbus-1.10.0.tar.gz glib-2.26.1.ta ...
- SprimgMVC学习笔记(十一)—— 解决静态资源无法被springmvc处理
方法一:在springmvc.xml中配置 <!-- 解决静态资源无法被springMVC处理的问题 --> <mvc:default-servlet-handler /> 方 ...