为什么我们在微服务架构中需要引入配置管理这个组件呢?
这里所说的配置管理就是配置中心。
首先我们着眼下需求,从业务场景上来说,为什么需要一个中心化的配置管理的集群,而不是将所有配置都放到你的服务本地。一般应用上,作为配置管理是非常简单的,甚至没有额外的配置中心,那么这种模式我们就是把一个应用部署在一个服务器上面,同时与这个应用一同部署的,还有一份配置文件,比如里面可以约定你的数据库连接Url,userName,Password,还有等等其他各种的配置。在SpringBoot项目上,大家非常熟悉Resources这个目录,在这个目录下,我们可以定义如application.yml这个样的各种配置文件。它随着你的应用一同部署在一个jar里面,这里面的配置项,随着你应用的加载一同被加载到上下文当中,这是一个比较典型的部署的模式。
这里有一个需求上的变化,如果有一天你的产品经理跟你说啊,我们不能再用王大锤的名号招摇撞骗,我们要把这个userName改成叫王大炮。那这一改不要紧,如果用上面那种经典模式,我们应该怎么做呢?很简单,配置文件当中把这个属性名改掉,然后去做一个重启,把应用重启,重新去加载配置文件到上下文当中。
这看起来似乎没什么问题,对于小型应用来说,往往我们也是采用的这种方式,非常的廉价而易于操作,但是我们想过没有,对于一些大型用,动辄成百上千的微服务,成千上万台服务器,如果我们还采用这种基于本地文件的管理方式,那每次有新的变更都要一顿操作猛如虎,把所有集群当中的服务器全部重启一遍,不要说BATJ这种巨无霸型应用,就是一些小型应用服务器,数量稍微那么一多,这种方式都不是一种很有效的方式。
那这就是我们配置中心的一个重要的功能,它要达到了一个目的,就是属性分发,让配置文件的内容,如何发到每一个服务器集群当中,每一台服务器上。这就是一个配置中心所需要满足的一个用户的场景。
从业务层面来看下,如果现在有三台服务器,每台服务器都有自己对应的配置文件,现在有这样的一个需求场景,它通过一个业务的开关来控制一个功能的开启和关闭。比如,我通过一个属性控制你服务的注册功能,是开启还是关闭?比如说我们有一些非常著名的论坛,他需要你提供一些注册码,邀请码,比如1024才能去注册,那么,它的注册功能呢就是处于一个关闭状态,如果有一天,我的网站搞活动,我想把网站的注册功能给开启,在这种情况下来,我们在传统的属性分发过程当中,就像前面提到的,我需要修改静态文件,然后再做一个重新的部署。一来操作非常麻烦,要处理整个集群的属性刷新;二来,你修改文件,重启服务器,这个时间的开销也是相当长的。与其使用静态文件的分发,不如我们有一个中心化的配置中心,可以实现属性变更的实时推送。
这样一来,就可以玩转很多不一样的业务场景。比如,我可以把一个属性推送到一个特定的服务器当中,这是什么场景啊?这就是我们典型的一个金丝雀测试的场景,在一台服务器上开启业务开关去验证你的业务。同时我们还可以做一些批量推送,对一些特定的服务器,把属性变更推送到他们上面,这就是咱们的一些蓝绿测试的场景。如果你的配置服务中心可以满足这样的实时推送。那么就是好处多多,你的操作节省了时间,节省了操作成本,并且增加了你的业务玩法,什么金丝雀测试、蓝绿测试都可以去正常执行。
再看一个跟写代码比较相关的一个场景。比如,这里有一个订单服务,一个订单服务从开始编写需求到最后上线,通常会经过很多个环境的验证,有日常的开发环境(Dev),测试环境(SIT),用户验收环境(UAT),还有在上线之前做的一个预发测试环境(Pre),以及最终正式版的线上环境(PRD),这每一个环境它的数据库连接串、账号、密码、以及各种的业务属性,通常来讲是完全不一样的。因此,我需要对每一个环境指定一个配置文件,如此一来,你就要把所有的配置文件都保存在你的本地项目当中,resource文件夹下面就会列出各个不同环境所需要用到的资源文件。
从这个角度,其实并没有很好的实践一个隔离的职责,因为你的配置文件,它和你的业务逻辑是紧密的联合在一块儿的,如果可以从业务层面把它剥离出来,也就是说不随着你的业务代码一同部署,而是在一个相对中心化的集群当中去统一的管理这些配置文件,这就可以做到一个职责的隔离,也就是我们常说的低耦合高内聚。
这样一来,其实本地并不需要保存这四份配置文件,你只有保存一份配置文件就够了。那系统如何知道该拉取哪一个配置项呢?很简单,我们在启动脚本,启动jar包的脚本当中,我可以把环境参数传入进去。在dev环境里面,可以传入dev启动参数,在uat环境里面,可以传入uat启动参数,以此类推。接下来,你的应用可以去配置中心上面,把对应环境的配置文件拉取到本地,这样一来,对于你本地的订单服务这个业务层面来说,它就做到了一个环境隔离,你不用关心当前是开发环境还是生产环境,所有配置属性的环境隔离,都交有配置中心那边来处理。
除了环境隔离以外,还可以做什么呢?一个系统当中有很多的微服务,例如订单、商品库存服务等,每个服务在不同环境还有多种不同的配置文件。如果商品服务也参考我们订单服务的做法,把以上的配置文件全部交由中心化的一个配置中心来管理,这样又对我们的配置中心提出了另外一个需求,什么需求呢?从服务层面要做一个隔离,它要知道哪些配置文件是给订单服务的,哪些配置文件是发放给商品服务的。
总结一下,对配置中心的三个需求点:
第一个,业务隔离。将配置文件从具体的业务代码当中抽离出来,放到一个中心化的配置中心里面。
第二点,环境隔离。业务代码层并不需要去关心自己当前部署的环境,由中心化的配置中心集群对不同环境的配置项做一个隔离,把它们分门别类的放到不同的文件当中。业务代码在启动的时候,根据当前启动参数中的环境名去拉取对应的文件。
第三点,服务隔离,既然是一个中心化的配置服务,那必须要有能力去识别哪些配置文件是属于哪些服务的。
下篇预告:配置中心的高可用