为了避免参数变化引起的频繁的程序改动,通常我们在应用程序中将常用的一些系统参数、启动参数、数据库参数等等写到配置文件或其他的存储介质里面。
- 配置常见的存储方式:配置文件、数据库等
- 配置对于应用程序是只读的,程序通过读取配置来影响程序的运行行为
- 配置是区分环境的同一份程序部署到生产、测试、开发、演示环境下,需要做不同的配置
传统应用程序的配置分散,导致了在进行部署、运维方面,需要极大的成本。那么传统的应用程序配置面临哪些问题?
问题一:应用程序多实例集群部署,每个微小的配置的修改将导致每个实例都需要重新打包部署
问题二:每一套环境的配置不同,难于维护,增加了人工犯错的几率

问题三:没有严格的配置管理权限控制,导致公司的核心数据泄露
不知道大家有没有看过一条报道,国外某著名的公司,在开源代码的数据库连接配置中,携带了其"生产环境"的数据库配置信息,导致其核心的用户数据泄露。
除了上面的三点,还有很多传统的配置管理方式面临的问题,所以我们要进行集中的统一的配置管理。这点在微服务应用中体现的更为明显。
比起“分布式配置中心”这个词,我更喜欢集中的配置管理中心叫做“统一配置管理中心”。“分布式”修饰的是应用程序,而“统一”才是修饰配置管理中心的关键词。但是大家都叫分布式配置管理中心,我也就从了大家。但是在理解上要区分过来。
理想的配置管理中心应该是:
- 支持多应用配置管理
- 支持多环境(生产、测试等)配置管理
- 支持配置权限管理
- 支持配置版本化管理、配置回滚
- 支持配置的动态发布、灰度发布(后文会给大家介绍)

配置中心将配置从应用中剥离出来,统一管理,优雅的解决了配置的动态变更、持久化、运维成本等问题。应用自身既不需要去添加管理配置接口,也不需要自己去实现配置的持久化,更不需要引入“定时任务”以便降低运维成本。总得来说,配置中心就是一种统一管理各种应用配置的基础服务组件。
在系统架构中,配置中心是整个微服务基础架构体系中的一个组件,如下图,它的功能看上去并不起眼,无非就是配置的管理和存取,但它是整个微服务架构中不可或缺的一环。
目前市面上用的比较多的配置中心有:
Spring Cloud Config
2014年9月开源,Spring Cloud 生态组件,可以和Spring Cloud体系无缝整合。
https://github.com/spring-cloud/spring-cloud-config
Apollo
2016年5月,携程开源的配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
https://github.com/ctripcorp/apollo
Nacos
2018年6月,阿里开源的配置中心,也可以做DNS和RPC的服务发现。
https://github.com/alibaba/nacos
如何选择
- 如果你希望完成单纯的分布式配置集中管理,其实三者都能满足你的需求。
- 如果你考虑到已经用Nacos实现了服务注册中心,不想单独搞出来一个配置管理中心,合二为一的话,nacoos可能是你的**选择
- 携程的Apollo与nacos很多相似之处,有颇多的亮点。从笔者的使用感受而言,目前apollo从文档细节到方便度要好于nacos(截止2020年4月)。但是nacos毕竟开源时间较短,依托alibaba的支持,有很大的潜力和发展空间。
- spring cloud config对比其他两者,在功能以及友好度方面都逊色。唯一的优点可能是它比较轻量级。
Spring Cloud Config Server提供了可水平扩展的集中式配置服务。它使用的存储库层作为数据存储,该存储层目前支持本地存储,Git和Subversion。其核心功能:
- 通过将版本控制系统用作配置存储,开发人员可以轻松地对配置更改进行版本控制和审核。
- 实现集中的配置管理,不同的环境、不同应用的配置通过文件名称进行区分。
- 支持运行时动态配置更新,即:配置的热更新
- 提供配置访问的REST接口

- 首先我们需要一个远程的仓库(在实际生产环境中,一般需要自己搭建一个服务器。方便起见,建议使用了开源中国的仓库或微软的)
- 其次我们需要搭建,微服务()应用在启动的时候会从中来加载相应的配置信息 。前提是微服务集成了的客户端程序。
- 当微服务尝试去从中加载配置信息的时候,会先通过命令从远程仓库克隆一份配置文件保存到本地 。这样当远程仓库无法连接时,就直接使用本地存储的配置信息
- 由于配置文件是存储在仓库中,所以配置文件天然的具备版本管理功能,中的功能可以实时监控配置文件的修改
虽然目前支持本地存储,,但是基于配置版本审核、管理,以及可用性的考量基础,几乎最终都是选择作为的配置仓库的管理工具。
考虑github连接太慢,下面使用gitee作为数据存储服务器
按照下面四个步骤我们来配置文件仓库:
- 用你自己的账号在gitee上新建一个作为配置中心数据存放的仓库

- 将仓库克隆到本地的一个文件夹中


3.在克隆下来的仓库中新建配置文件,将之前系列中的rabc项目配置文件和sms配置文件复制进去,并进行改名,改名规则如下:
其文件命名规则为:
- 表示项目的名称,即:的配置值
- 代表基础环境,通常是指:等等。

4.添加文件到暂存区–>提交本地库


5.推送到远程仓库

将以上的本地配置文件及文件夹与远程仓库(gitee或github)同步,我们的git仓库构建工作就完成了。

构建Config Server
和Eureka Server一样,netflix出品的Config Server也是基于SpringBoot项目的。
所以我们在spring-cloud新建一个module:dhy-server-config。

如果没有搭建父工程的,可以选择参考之前系列进行搭建,或者只引入相关依赖,测试使用
通过maven坐标引入关键类库:spring-cloud-config-server
在项目启动类上面加上注解


在application.yml中进行config server的基本配置。
- spring.cloud.config.server.git.uri:配置git仓库位置的http访问地址
- spring.cloud.config.server.git.searchPaths:配置仓库路径下的相对搜索位置,可以配置多个。
- spring.cloud.config.server.git.username:git仓库的用户名
- spring.cloud.config.server.git.password:git仓库的用户密码
如果把配置文件放在目录中提交上去,那么searchPaths就是该目录的名字,指明我们需要的配置文件在哪个目录下面
config server访问测试
config server构建完成之后,我们可以通过浏览器URL访问测试,读取配置文件。
其如下:
- 就是应用名称,对应到配置文件上来,就是配置文件的名称部分,例如我上面创建的配置文件。
- 就是配置文件的版本,我们的项目有开发版本、测试环境版本、生产环境版本,对应到配置文件上来就是以
加以区分,例如 - 表示 分支,默认是 分支,如果项目是以分支做区分也是可以的,那就可以通过不同的
来控制访问不同的配置文件了。
所以我们的这两个配置文件,可以通过(以为例):

- http://localhost:8771/dhy-service-sms-test.yml
- http://localhost:8771/master/dhy-service-sms-test.yml
- http://localhost:8771/dhy-service-sms/test/master
- http://localhost:8771/dhy-service-sms/test

通过访问以上地址,如果可以正常返回数据,则说明配置中心服务端一切正常。至此,说明和远程仓库之间的配置同步已经通了(红色边框部分)。

但是,大家可以明显的感觉到这里遗留了:
那就是任何一个人都可以通过浏览器去访问任何一个项目的配置文件。关于配置的安全与权限管理做的肯定是没有那么好,但是也是有一些可以自己实现的安全认证方式,否则就太不安全了。我们后面的章节会讲到。

从上图中,通过前面章节的讲解,我们已经实现了如下内容
- 建立仓库,我们已经可以向仓库提交配置文件了
- 搭建了做统一的配置管理,可以从配置仓库拉取配置文件
本节就为大家讲解第三步:
在dhy-service-sms和dhy-service-rbac服务的pom.xml中引入spring-cloud-starter-config依赖:
配置(以dhy-service-sms为例),来指定config server,例如:
- spring.cloud.config.profile:对应前配置文件中的{profile}部分
- spring.cloud.config.label:对应前配置文件的git分支
- spring.cloud.config.uri:config server配置中心的地址
这里需要格外注意:上面这些属性必须配置在文件中,而不是l中,配置内容才能被正确加载。因为加载优先级高于,保证在应用一起动时就去加载配置,对于 中一些自动装载类来说这很重要。
当使用 的时候,你应该在 里面指定 和和一些加密/解密的信息
:在 项目 中 服务启动后,,然后获取 配置。)。 所以, 我们将绑定
以application.yml 为配置文件启动日志会有如下信息:
当使用 的时候,配置信息一般是从 加载的,为了取得配置信息(比如密码等),你需要一些提早的或引导配置。
因此,把 信息放在 ,用来加载真正需要的配置信息。
这是由的加载属性文件的优先级决定的,你想要在加载属性之前去上取配置文件,那相关配置就是需要最先加载的,而的加载是先于的,所以要配置的相关配置就只能写到里了。
最后,我们把application.yml中的配置全部注释掉(如下图)。因为这部分配置,我们已经全都放到git 仓库中进行集中管理,我们的服务通过config server就可以获取到。

- 首先启动日志,明确的输出:项目在启动的时候去加载配置。加载的是,也就是:完全和我们的预期一致(和本文上面内容的配置一致)。

- 然后我们再看dhy-service-sms是否向eureka成功的进行了服务注册

是本地应用注释掉了,但是我们已经把它转移到远程配置管理仓库中了。
这也再次验证了,aservice-sms正确的应用了远程git仓库和config server进行集中的配置管理。

在前面章节我们已经为大家介绍了Spring Cloud config进行配置管理的基本流程。在使用Config Server的时候,我们可以通过一些固定模式的http-URL,没有任何限制的访问到项目的配置文件信息,这样很不安全。
为了解决这个问题,我们可以使用spring security进行简单的basic安全认证(也可自定义认证方式,这里不做扩展,需要深入去学习Spring Security)
在dhy-server-config的pom文件中增加依赖:
配置文件application.yml增加security配置:
启动服务,测试一下。请求 ,会发现弹出了security的basic登录验证:

输入我们自定义的用户名密码,返回请求配置信息。这种方式实际上也是一种简陋的安全认证方式,但总比没有强。
当config server增加了登录认证之后,我们的微服务客户端想要正确的获取配置信息,在发送请求的时候也要携带用户名密码。
修改配置文件bootstrap.yml,增加username和password配置:

首先启动config server服务端项目:dhy-server-config,然后启动dhy-service-sms和dhy-service-rbac服务。

- 一是日志中明确输出了获取到对应的配置文件信息。
- 二是微服务正确的向服务注册中心eureka’进行了注册。

至此,spring cloud config安全配置完成~
配置发生更改之后,将配置值的结果更新到客户端程序中。因此我们首先要明白两个问题:
- 哪些配置刷新之后可以更新,哪些配置刷新之后也无效?
在谈配置热更新以前,我们先将配置分成两类:
- 第一类是影响应用运行状态的配置,这一类的配置通常会影响Spring Bean的自动装载。比如:数据库连接配置,在应用启动的时候会自动根据数据库配置初始化一个数据库连接池,连接池中保存着n个激活的数据库连接,以供业务持久化操作调用。这一类的配置是不能热更新的,或者准确的说即使配置数据本身更新了也没有用,数据库用户名密码配置更新了不等于数据库连接池里面的连接对象也更新了。配置背后的应用对象重构工作,config是无法帮你做到的(配置更新后只有应用重启才能生效)
- 第二类是业务运行所需的数据,比如:新建用户时的默认密码,重置用户时的默认密码。这一类的配置发生变更修改的就是配置数据本身,它不去影响程序的其他对象,不产生其他的连锁反应。
2.可以对哪些注解标注的配置进行刷新。下面两个例子都可以将键对应的值热更新到对象上。
3.这两个注解需要结合注解使用才能使配置热更新生效。
下文中会针对这种注解的方法为例进行讲解。
因为config底层是基于RefreshEndpoint实现的配置刷新,因此需要引入actuator相关依赖,开放相关的端点
该依赖是加在客户端,是客户端需要刷新配置
actuator为我们提供“/actuator/refresh”配置刷新接口
- management.endpoints.web.exposure.include=refresh,health,表示我们只开放配置刷新接口和健康检查接口,下面这段配置可以加载git仓库中对应的客户端yml文件中
例如: 我们这里需要动态刷新dhy-service-sms的配置信息,我们就将下面的配置加在gitee仓库中该微服务对应的yml文件里面

在需要进行配置刷新的类上使用,对应的配置对象的值就初步具备刷新的能力。
测试初始自定义配置是否生效
使用postman向“/sms/send”接口发送请求,测试配置是否能够正常拉取到

去gitee上面手动更改配置内容如下

当我们更改了gitee上面的配置文件后,配置中心config已经完成了最新版配置的拉取,还剩客户端需要从config配置中心手动拉取到最小的配置,下面验证config配置中心已经是最新的配置了

这里的乱码是因为没有提前告知浏览器返回的中文字符用什么字符集进行解析造成的,可能浏览器使用gbk解析,但是gitee上面是utf-8编码的
- 通过请求发送到,触发的配置进行刷新,返回值是刷新了哪些配置项

客户端验证是否得到最新结果:

那么有没有一种方法,能够实现配置修改之后,自动去向发送请求,更新配置?
是有方法的,但是不好。实际生产中几乎没法用,不好也给大家说说,学习一下。
我们可以在仓库中配置一个,所谓的作用就是每当仓库有接收到代码请求时,都会去向自定义指定发送请求。我们完全可以利用进行配置的自动刷新。

这是一种方法给大家放在这学习一下,但是笔者重来没这么做过,基于以下几点原因:
- 微服务客户端必须提供公网地址才能访问到,实际生产或开发环境谁会把自己的内部服务全部暴露到公网?(上图中的127.0.0.1要换成公网ip才可以,内网ip是无法访问到的)
- webhook发送请求是无法区分项目、无法区分环境的。该向哪一个项目的,哪一个环境,哪一个实例发送/actuator/refresh请求?不能随便配吧。
- 最重要的原因:程序员提交代码的行为不可控,不能因为配置代码变更了就认为这种变更是正确的,不代表可以自动的应用到环境中。
基于以上原因,都不如自己决定向哪里发送请求。甚至写一个简单的管理程序,都比使用强。当然如果我们想通过实现微服务配置的全量刷新、批量刷新、局部刷新,还有终极解决方案,那就是结合使用,后面章节我们会讲到。

Config Server实现高可用的原理比较简单:因为Config Server 是用Spring Boot构建的, 所以我们完全可以把它当做微服务注册到eureka,启动多个实例向eureka注册,并对外提供服务即可。
- 我们的业务服务(如dhy-service-sms)和Config Server都向Eureka注册,所以aservice-sms可以通过eureka获取ConfigServer服务列表
- dhy-service-sms通过负载均衡策略,在多个Config Server实例中选择一个作为获取配置请求的发送目标。
所以:
- 首先我们要有eureka集群,这个搭建我们前面已经讲过
- 其次我们要调整Config Server集成eureka客户端,从而使Config Server能够作为eureka客户端服务存在,实现服务注册与发现。
- 最后我们需要调整dhy-service-sms(既是Config Client、又是Eureka Client),以便适应从eureka获取Config Server服务列表。
其实Config Server作为一个服务向eureka注册,和普通的微服务向eureka注册没有什么区别。
为了加深大家印象,我就再讲一遍:要想让Config Server实现服务注册功能,首先引入spring-cloud-starter-netflix-eureka-client。
在application.yml加入eureka相关的配置
在dhy-server-config的启动类上加上注解

此时启动config server,再去看eureka注册中心,验证是否注册成功即可
我们的微服务客户端(如:dhy-service-sms和dhy-service-rbac)作为config client需要调整配置。

- 原来直接通过URI访问config server单节点,现在调整为通过service-id到eureka注册中心发现config server服务集群。(上图红色边框部分)
- 另外需要加上eureka 客户端配置(上图橘色边框部分),why?这个不是不是已经放到仓库集中统一管理了么?
- 在没有实现高可用的config server之前,我们是URI直接访问config server,获取项目配置。响应结果配置中包含eureka
server配置,从而微服务可以向eureka集群注册。所以eureka客户端配置可以放在远程git仓库。 - 现在我们为了实现高可用,把config server作为eureka client注册到eureka集群。所以我们的其他本地服务想找到config server获取配置,必须先找到eureka服务注册中心,才能找到Config Server。所以eureka客户端配置必须放在本地服务中才行。


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/171643.html