编辑推荐: |
本文来自微信号EAWorld,文中从配置与程序的关系,动静态配置结合模型及方案方案来讲解配置管理的能力。 |
前些年没提微服务架构的时候,大家也都会做配置管理相关的事情,比如我接触过的很多项目都做有配置,做得有好有坏。大多是手工作坊,修改配置、重启服务… … 好像也能凑合。其实不论有没有微服务,把配置管理好的手段和方法都差不多,只是微服务架构重分布式的特点凸显了这个问题的重要性,再不管好配置,还想继续凑合就行不通了。本文目的是跟大家一起梳理配置管理的一些思路和方法,一起打好微服务架构的基础。
目录:
一、什么是配置
二、配置与程序的关系
三、配置管理的四个维度
四、静态配置管理
五、动态配置管理
六、总结回顾
一、什么是配置
配置是独立于程序的变量①,配置通常有各种形态,有配置文件、数据库表、系统环境变量、进程启动参数等。
一般我们会把配置按程序启动为分界线,分为两类:
运行前的配置
运行前的配置,通常是指与环境相关的一些配置,比如数据源、邮件服务器地址,不同的环境有不同的值。还有一类比如安全控制类的,例如weblogic服务启动时,会要求输入启动账号密码等。把程序与环境相关的参数设置好之后,才可以在对应的环境上正常启动运行。
运行时的配置
运行时的配置,通常就是一些可以动态调整的参数,程序会根据不同的参数值产生不同的行为,计算结果可能不一样。一般运行时的配置调整,最好是能够做到动态的热更新,不需要重启动服务才能生效。大致分两种:
技术运维相关的参数,如线程池大小、队列长度,调整为不同的值会有不一样的性能表现。
业务相关的参数,比如贷款系统贷款额度调整,贷款利率调整。
二、配置与程序的关系
配置管理的前提是程序与配置要分离,如果是写死代码的话,配置管理也就无从谈起了。
其次就是一套程序支持多套配置,这是针对静态配置来说的,一套程序,不同的配置值,适应不同的环境。
运行时,程序是稳定的,配置是可变的 ,还需要将配置持久化保存,不要放到虚机和容器的内部存储中,避免虚机、容器重启动后配置丢失,还原成镜像的最初状态。
参见上图,介质+配置=部署包这个公式主要是针对静态配置说的。介质就是程序,配置就是适合环境的配置值,两者组合成的部署包就成了某个适合具体环境安装部署的部署包,有了这个环境部署包,我们就可以非常方便的把部署包安装到对应的环境中。
三、配置管理的四个维度
配置是需要治理的,配置管理的过程中,我们需要考虑下面这四个维度。
多环境管理,维护好环境与配置的关系,即不同环境不同配置(静态配置相关)
影响范围控制,运行时配置变更后,会影响单点还是集群,是只影响一个应用,还是会影响多个不同的应用(动态配置相关)
配置管理过程需要有权限控制,严格的话配置变化还需要有流程审核才能发布。
配置变更操作需要审计,要知道什么人、什么时间修改了哪些配置。每次修改发布都要留痕,也就是有多版本,一旦修改出了问题,可以进行回退操作,恢复到修改之前的状态。
四、静态配置管理
先来看一个反例,一些企业比如金融行业,非常重视上线过程的流程和操作合规性的,但现状是没有技术手段支撑,全是手工操作,开发人员和运维人员都很痛苦,整个上线周期很长,非常容易出问题。
见上图,功能开发结束后,开发人员为了上线,先要准备一堆文档,比如操作手册,要求写成运维人员不需要思考,完全机械化的按步骤复制、粘贴就能完成操作的状态。比如在什么目录下某个文件里面,配置数据源,然后在负载均衡什么目录下配置Ip端口等等。
先写个半个月文档,然后评审,接下来再演练,反复进行好多次,最后才能上线。开发工作量和上线过程的工作量几乎到了1:1 效率非常低下。
那么推荐的做法是要流程和技术并重,通过自动化的手段,将介质和配置组合,打出适合某环境安装的部署包,更方便的部署到开发环境。
见上图,集成过程中设置好配置值,编译后可以直接注入配置作出部署包,如果有自动化部署服务能力的话,就能够自动的吧部署包发布到对应的环境中了。即便是没有自动化部署,一个已经配置好的应用部署包,手工操作起来也是很简单的事情,解压到合适的位置就好了。下面推荐两个静态配置管理的方案供大家参考:
方案一:Spring Profiles
Spring Profiles②是Spring推出的功能,提供了应用程序在不同环境中使用不同配置的能力。
比如在spring boot应用中的用法。如果使用properties文件存储配置时,可以为每个环境分别设置一个配置文件。
如果项目中使用了yml格式的配置文件的话,不同环境的profile需要在同一个配置文件里面定义,示例如下:
定义好后不同profiles的配置后,在Spring boot应用启动时,可以通过参数指定激活某个profile,然后Spring boot程序就会加载对应profile下的配置值,启动参数激活方式示例如下:
方案二:AutoConfig + SCM
AutoConfig③: 阿里系的一个开源工具,提供了在build时刻基于文件进行配置注入的能力。类似于Maven Filtering,但其使用方式与开发应用所采用的技术框架无关,具备良好的通用性。(AutoConfig源码库地址:https://github.com/webx/ citrustool/ tree/master/antx/autoconfig)
参见上图,AutoConfig 配置注入主要分三个步骤。有了模板和配置元数据的定义再加上配置值,就可以通过命令把配置值注入到目标文件里面。工具非常强大,针对的是目标文件,不依赖编译框架。在编译中或者编译后都可以执行,还可以注入压缩包内的配置文件。
配置模板抽取:
application.yml 源配置文件示例
application.template 是根据application.yml抽取出来的配置模板。其中${}内的字符就是配置项名称。示例如下:
配置元数据定义
auto-conf.xml 即配置元数据定义文件,文件中主要包配置项的定义和注入脚本定义两部分内容。示例如下:
配置文件注入
通过命令行注入配置文件示例如下:
SCM④: 普元自建的一个配置管理服务,支持对应用在交付过程中的不同阶段和环境的配置进行统一管理。我们反复再强调,配置管理是软件交付过程中的非常重要的环节。
如果说没有软件配置管理的话,项目将是个什么样子?开发人员没定义或者乱定义,测试人员不会装不会配,上线的运维人员更是一头雾水。这种状态下,想要成功上线,就只能回到严格控制流程,逼开发写文档,逼测试演练,逼运维转型机器人。大家都干着枯燥无味的事情。
那么SCM的作用就是要支撑软件配置的协作化管理 ,通过SCM提供的能力,可以让开发人员在设计过程中,规范的定义配置项,并设置好默认值。测试人员负责设置测试环境需要使用的配置值,运维人员负责生产环境的配置值,做好这些后,持续集成和交付服务可以快捷的编译出部署包并安装到目标环境里。SCM在配置版本、环境、角色、权限、流程等配置管理的多个维度均提供了相应的能力支撑。
上图是是我们的DevOps产品中的一个CI、CD示意图。开发、测试、运维人员,通过门户UI去设置不同环境的不同配置值,然后发起编译、打包、部署操作,后台就由各服务自动的进行源码编译、配置注入、自动部署等操作。
开发人员不用写那些一堆上线操作手册了,只需要定义配置项,设置默认值。测试人员、运维人员也都设置自己维护环境的对应配置,评审都是在线进行,审核通过,点个按钮就自动部署。总之能让机器代劳的工作,尽量少让人手工干。
SCM服务的主要概念模型如下图:
一个业务系统可以由多个组件(微服务)
组件是部署的最小单元
一个组件可以定义多个配置项
一个配置项对应不用环境可以有不同值(每次环境配置提交均全量留痕,打部署包时可按需选择)
在我们DevOps产品门户中已有环境配置管理的应用,组件部署设计中配置项设置相关的页面截图如下:
静态配置管理的两个方案对比如下:
Spring Profile方案:
说明:Spring体系能力,能够与Maven、Jenkins集成。适合一般项目中使用。
优势:配置简单,使用方便
劣势:环境配置存放到代码库中,权限不好控,安全性一般;技术框架有限制(Spring),灵活程度略低(依赖Maven编译)
SCM + AutoConfig方案:
说明:更体系化的配置管理整体方案,更适合企业整体规划。
优势:完善的配置权限管理;不限制技术框架;针对的是目标文件,更灵活。
劣势:需要开发维护SCM服务
五、动态配置管理
首先看图回顾一下前面提到了动态配置的一些要点:
动态配置通常包含,业务运营配置,和技术运维配置。动态配置管理,通常就需要考虑右边这三个维度,影响范围、权限控制、审计很多版本,最后还有一个隐含的要求就是要支持热更新。
那么传统动态配置管理的方案和微服务架构下的管理方式思路基本一致。主要是这三个方面:
状态统一管理
中心配置仓库
配置推送和拉取
传统模式和微服务架构的区别就是,以前分布式程度低,很多情况都是手工维护。比如应用状态管理、集群配置都是手工维护的。很少有做配置修改审计和回滚的。微服务架构下,我们需要更加灵活,快速变化。那么应用需要自动注册发现,应用很分散,审计的需求加强了,异常回退的需求也来了。那么久需要适应微服务架构下的配置管理方案,示意图如下:
我们的微服务平台配置中心是选用了携程开源的Apollo①,也是功能非常强大,需要的能力基本都是现成的。Apollo配置中心能够方便的与注册中心集成。我们的微服务平台是基于Spring Cloud,而Apollo也是能够跟Spring Cloud这套环境很好融合。Apollo的主要概念模型如下:
App:应用
Cluster:集群
Namespace:名称控件(可以类比为文件)
Item:Namespace下的配置项,每个Item是一个key, value组合
Release:Namespace发布的配置,每个发布包含发布时该Namespace的所有配置
Commit:Namespace下的配置更改记录
基于Apollo配置中心,我们的微服务平台管理门户中可以方便的管理各微服务应用中的配置,通过管理门户统一控制配置权限,每个配置项修改分为保存、发布两个动作,发布过程可以支持流程审核。配置项值变更多版本记录,可以回滚到某个历史版本。见下图:
六、总结回顾
最后,我们用一张图⑥来总结回顾一下:
本文讲的配置管理,主要就以运行前的静态配置和运行时的动态配置入手展开的。配置管理的前提,就是程序和配置要分离。静态配置考虑多环境,要管理配置和环境的关系,动态配置要考虑变更影响范围。两者都需要考虑的是权限、审计、多版本等内容。
那我们要做好配置管理,需要在不同的阶段,配合一些手段来逐步实现。首先是定规范要求程序和配置分离,然后统一打法选合适的技术框架,让配置定义、加载、热更新等方式尽量统一,最后平台化做规范化的集中配置管理。
参考资料:
① 开源配置中心Apollo的设计与实现
http://www.infoq.com/cn/ articles/ open-source- configuration-center-apollo
② Spring boot profiles
https://docs.spring.io/spring-boot /docs/current/reference/html/ boot-features-profiles.html
③ AutoConfig工具使用指南
http://blog.csdn.net/ fighterandknight/article/details/70245905
④ DevOps之软件配置协作化管理
⑤ 基于微服务的企业应用架构设计范式