本文spring-cloud 版本为:hoxton.sr6
本文spring-boot版本为:2.2.x-2.3.x
… …
前言
在开始学习使用config配置中心的时候呢,我们首先,有几个疑问
一、什么是配置中心
二、为什么要使用配置中心(或者说,在分布式项目中,不使用配置中心会面临哪些问题?)
在回答问题一的时候呢,我们可以先看下问题二,进行思考一下,当思索出问题的时候呢,我们自然就能窥见一点端倪…
我们在生产环境部署的时候,为了服务的可用性以及负载,通常一个服务会启动多个实例,要么在不同的机器 要么在相同机器不同端口…
例如 商品服务启动4个,订单服务启动4个,用户服务启动N个,文件上传服务启动X个等等…
当服务启动的时候便会去加载自己的配置文件application.properties
或者application.yml
一气呵成…这本身,是没有问题的
我们总会面临因业务更改导致配置文件需要新增/修改/删除属性的时候…如果有了这样的场景,我们该如何应对呢??
1、更改配置文件后,从新打包部署?
2、配置文件存放部署的服务机器某路径上,更改保存再重启服务?
3、如果每次更改配置文件后,都需要重启项目,好费时间?
以上,第二种方式可能效率更高一点…但是我们微服务通常又是使用容器化部署,如果保存在宿主机某一处的话,也是涉及到目录挂载问题的,且在服务器上,不方便多个服务统一管理…
因为种种问题,有了需求,自然就有其实现,于是 分布式统一配置中心出现了…
config(配置)又称为 统一配置中心顾名思义,就是将配置统一管理,配置统一管理的好处是在日后大规模集群部署服务应用时相同的服务配置一致,日后再修改配置只需要统一修改全部同步,不需要一个一个服务手动维护,简化部署时间,方便服务配置统一管理.
官方地址:https://docs.spring.io/spring-cloud-config/docs/2.2.5.RELEASE/reference/html/
Spring Cloud Config为分布式系统中的外部化配置提供服务器端和客户端支持。
使用Config Server,您可以在中心位置管理所有环境中应用程序的外部属性。
客户端和服务器上的概念与SpringEnvironment和PropertySource抽象,
因此它们非常适合Spring应用程序,
但可以与以任何语言运行的任何应用程序一起使用。在应用程序从开发人员到
测试人员再到生产人员的整个部署过程中,
您可以管理这些环境之间的配置,并确保应用程序具有它们迁移时所需的一切。
服务器存储后端的默认实现使用git,
因此它轻松支持带标签的配置环境版本,并且可用于管理内容的各种工具。
添加替代实现并将其插入Spring配置很容易
微服务接入统一配置中心后流程:
服务在启动时首先回去配置中心读取配置,配置中心从本地库(比如 存于服务器某处)或远程库(gitlab、码云等)拉取到配置后,交由服务…
配置中心组件
其可以极为方便的帮助我们统一管理服务配置,但其并不是一个微服务架构所必须的组件,至于是否使用,全看自身是否后续考量服务配置是否高效管理…
config配置中心 分为服务端
和客户端
服务端:作为一个服务配置读取的中转站,其要做的事情便是 寻找拉取配置
,配置交由服务
客户端:即原本服务需要订阅到配置中心服务端,当需要服务时去请求服务端,以拉取到自身配置
那么…接下来,咱们便开始对我们的微服务做一个配置中心组件接入
配置中心服务端,也需要其作为一个单独的服务进行开发…
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-serverartifactId>
dependency>
@EnableConfigServer
此注解 打上以后,才会开启配置中心服务端功能 即拉取配置、拉取后交由服务
作为consul客户端进行注册
server:
port: 8888 #端口
spring:
application:
#服务名称 库存服务
name: service-config
#开始配置consul的服务注册
cloud:
consul:
#consul服务器的主机地址 默认:localhost
host: localhost
#consul服务器的ip地址 默认:8500
port: 8500
discovery:
#是否需要注册
register: true
#注册的实例ID (唯一标志)
instance-id: ${spring.application.name}-1
#服务的名称
service-name: ${spring.application.name}
#当前服务的请求端口
port: ${server.port}
#指定开启ip地址注册
prefer-ip-address: true
#当前服务所在 ip ${spring.cloud.client.ip-address}
ip-address: 192.168.124.17
我们来尝试启动服务:
发现报错…
If you are using the git profile, you need to set a Git URI in your configuration. If you are using a native profile and have spring.cloud.config.server.bootstrap=true, you need to use a composite configuration.
此错误信息提示我们,当开启了配置中心功能后,必须指定本地 或远端配置仓库路径
OK,那么我们便来创建一个仓库…
我这里使用码云 作为我的配置仓库 您也可以自行选择 gitlab /github等
spring:
cloud:
config:
server:
git:
# 远程库地址Url 在仓库处copy即可
uri: https://gitee.com/leileispace/config-repository.git
username: 账号
password: 密码
force-pull: true
# 指定额外搜索的路径 例如 你根据业务不同 对每个模块还额外建立了文件夹储存时。则用此配置,添加搜索文件夹的范围
search-paths: product
需要在配置文件中,添加以下配置
成功启动,接下来,咱们就尝试一下,通过config服务端 读取我们设置的demo-product
配置文件
如何访问呢?
http://localhost:8888/demo-product.yml
既可以:
config服务端ip:端口/分支/文件名.后缀
也可以:
config服务端ip:端口/分支/文件名-环境.后缀
其实我个人是不太推荐什么profiles
(环境)的这种访问方式的
因为实际开发中,开发代码dev 与生产代码prod 是使用git 或者svn分支来隔离开来的,不会存在说什么一套dev代码配置应用于多个环境,那不可能,每个环境的数据库、配置等是不太一样的嘛,何况大公司,小码农一般也没有合并分支的权利,看不见或者不能更改master分支的代码…
所以…注重开发流程的公司也不会存在一个profiles 多个环境的配置文件 比如你在dev 环境中 既有xxx-dev.yml或者xxx-prod.yml…,实际上 开发环境 只有一个配置文件xxxxx.yml 生产环境某一服务也只有一个配置文件xxxxx.yml
因此,我个人推荐config服务端ip:端口/分支/文件名.后缀
这种方式,且建议,一个环境一个配置,拜托啦!别把所有配置放一个环境了!注重分支概念好吗!
config服务端ip:端口/分支/文件名.后缀
# 服务端ip端口: 没什么可讲的
#分支:即 config仓库所在的分支:master、dev、test、fixbug....等等一些自定义的分支,默认不写则访问master分支
#文件名:一般一个配置都是以服务名为命名的...例如你的服务叫dodo-user,那么你的配置文件名也设置问dodo-user
#后缀:后缀可多样化. 比如 json、properties、yml等 实际上,如果你仓库后缀设置为yml 那么访问时请求后缀为.json、properties 一样是可以访问到配置文件的
当我们每在页面上拉取一次配置,发现本地服务控制台都会打印一些日志
其吧远程配置缓存了一份在本地…但目录嘛…一眼难进,,如果觉得不妥,可自定义本地库位置
#注意了:指定的目录一定要是一个空目录,因为其会吧本地设置的目录打成一个git仓库时会提前清空目录下所有内容..
spring.cloud.config.server.git.basedir= 本地目录
注意:指定的目录一定要是一个空目录,其会在初始化时吧目录下所有文件清空的额!!!!!!血泪教训!!!!!
配置中心服务端基础功能就完了,一个简单的服务中心你只需要三步,来回顾下:
(1)引入依赖
(2)开启注解
(3)配置(注册中心客户端配置、config-server 仓库配置)
在上边呢,我们已经通过注册中心服务端访问到了我么放于git仓库中的配置文件,证明了config-server服务端功能是Ok的,那么接下来呢,咱们就基于我们原本的项目进行改造,将原本项目中的配置文件迁移到我们的远程git仓库上…然后看看我们服务是否能正常启动且读取到远端Git仓库的配置文件
既然配置中心为一个功能,我们要使用它,那么首先,肯定需要它的依赖吧!
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-configartifactId>
dependency>
依赖有了,咱们还需要将其功能进行开启
如何开启呢?配置文件属性打开即可
首先,我们改造我们的demo-order服务
原本配置:
将原来配置文件存放到git仓库
改造后的客户端配置文件…
spring:
application:
#服务名称
name: demo-order
cloud:
config:
discovery:
#是否开启 config客户端
enabled: true
#config 服务端的名字
service-id: service-config
#拉取的分支
label: master
我这里演示,则直接使用master
了,我们在开发时,直接指定label为dev
分支即可,当然,前提示git远程库dev分支存在该项目配置,这样就保证了配置文件环境的隔离
OK,然后,来启动咱们的服务demo-order
首先,需要将原本的aplication.yml
或者applicaton.properties
项目配置文件更名为:bootstrap.yml
或者后缀为.properties
如果不更名,咋会不等待从config-server服务拉取配置直接启动,会报错…
demo-order
服务呢,整个启动过程如图所示:服务一起动便去配置中心8888拉取配置(通过项目中定义的服务名,以及label),拉取到配置后则加载远程配置文件内容,进行属性填充,然后启动项目
如图所示,服务拉取到了配置,并成功启动,且端口号为9002
我们再来看下,其是否注册到了我们的注册中心
已经成功注册到了我们的consul注册中心,即证明了config 客户端完成!能够通过config服务端读取到远端的配置文件并正确启动
…那么或许小伙伴有些疑问,那有时候我不小心设置了配置与远程库配置重叠了咋办,哪个有效呢?接下里,咱们测试一波!
即本地配置了一个配置,但远程配置文件中,已经有了改配置了,谁会生效呢?
咱们可以来测试一下:
比如:远程库配置文件中端口号为:9002
项目中配置文件再次重复设置端口号为9874
再次启动!
哎!发现其启动时仍然是首先去了配置中心服务端拉取到了配置,然后启动,本地的端口设置server.port=9874
并未生效!
然后,我们再模拟一个场景:
本地新添加配置,远程库配置不更新,测试本地配置是否生效!
可以看到,当远程仓库中无该配置,但本地库新添加配置亦可以生效!
于是,咱们在远程仓库中配置一样的属性,但属性值做一些改变再测试!
重启demo-order
项目,访问url
可以看到,本地配置属性student.name
已经被远程库配置所覆盖…
因此,我们可以得出一个很重要得结论!!!
远程配置内容与本地配置内容重叠时,以远程配置内容为准!本地配置为新增配置时,可直接作用于项目中!
远程配置内容与本地配置内容重叠时,以远程配置内容为准!本地配置为新增配置时,可直接作用于项目中!
远程配置内容与本地配置内容重叠时,以远程配置内容为准!本地配置为新增配置时,可直接作用于项目中!
以上呢,便是config统一配置中心的基础内容了!
附上config配置中心服务端demo:springcloud-hontox-sr6-config-server