配置管理
什么是配置: 独立于程序的可配变量。一般根据运行环境需要按需设定。
简述
当前常见配置传递方式
- cli 参数
- 环境变量
- 配置文件
- 接口传递: 服务自身开放的接口
- 配置中心获取: Consul, nacos, apollo 等
- Terraform + git 的 IaC 模式
- Helm / Kustomize 方式
- Spring Cloud Config + git 方式
常见配置文件格式
- .ini
- .yaml
- .toml
- .json
- .env
- .conf
配置分类
静态配置
1. 基本不变的配置
一般情况下是不会变的, 如果变了肯定是项目大改。
如 项目名称, 密码位数, 固定的启动命令等。这类配置可以直接硬编码到代码里面, 或者静态文件加载, 做到容器内部。
2. 启动时才确定的配置
启动时一次性配置好, 在程序运行期间一般不会改变,改变就必须重启服务的。
如 环境相关配置, 安全相关配置, 主机名, ip 地址,数据库名等。
一般在启动脚本内或环境变量内。
动态配置
在程序的运行期可以根据需要动态调整的配置
例如:
- 应用配置: 缓存池大小, 日志输出级别
- 业务配置: 价格, 汇率, 活动规则
- 功能开关: 启停
一般改变方式:
- 从数据库配置表获取
- 暴露外部管理接口, 传递进来
- 从配置中心拉取或推送
内外部配置
属于逻辑分类。即程序自身的配置和外部的配置。
自身配置: 实例名, JVM 大小等
外部配置: 如远程接口地址, 远程的 URL 路径, 账号密码等
一些常见的配置文件管理方式
1. 独立配置文件
即每个服务独立一个配置文件,变更时逐个修改和reload
2. 集中管理模式
即通过自动化工具推送一个配置文件到各节点,再远程reload服务,本质上和独立模式相同;或采用工具批量修改的方式
3. 配置中心模式
集中式存储和变更配置, 应用程序启动时拉取, 并 watch 接口监听变更;
4. git仓库管理 所有配置都在仓库内
配置变更发布的阶段
第一阶段: 人工线上修改并重启服务。
第二阶段: 本地修改配置文件, 通过自动化工具推送配置+重启, 例如 ansible
第三阶段: 配置中心手工修改配置, 手工重启服务或 watch 自动应用。
第四阶段: git管理, CICD自动应用部署。
应用配置的注入方式
打包时注入
在打包的时刻,构建脚本可以将配置信息与二进制文件一起,注入到部署包中
场景: 少量静态配置文件,或配置每次改变都会涉及代码同步变更时;
优点: 打包和部署的过程比较简单,不同环境使用特定的部署包;
缺点: 环境、应用、配置紧耦合,灵活性低;
部署时注入
在进行部署时,部署脚本获取基础配置以及不同环境特定的配置项,动态生成每个环境所需的配置信息; 相当于基于配置模板文件,在部署时再实例化为将要部署应用的具体环境的配置
场景: 大量的配置项,一些配置项在不同环境中存在差异 优点: 可以使用部署脚本或工具,动态生成特定环境配置信息 缺点: 需要维护应用与配置版本的匹配关系,增加了复杂度
运行时拉取和监听
在应用应用启动或运行时,通过外部的配置服务拉取应用配置(如通过REST风格的接口) 主流微服务架构都采用此模式;
场景: 频繁变更配置项,或者需要动态加载应用配置 优点: 部署包与配置彻底解耦,具备较高的灵活性 缺点: 需要考虑配置中心的高可用性和配置变更的原子性
配置中心
传统配置管理方式存在的问题
-
配置散乱格式不标准
-
主要采用本地静态配置,配置修改麻烦
-
易引发生产事故, 如漏改了1个文件;
-
配置缺乏安全审计和版本控制功能
-
上下游不解耦,下游变动影响上游:
例如下游系统在集群中增加了一个ip地址或账号密码, 可能需要多个上游业务系统配合进行配置变更。
-
下游服务不知道有多少个上游系统在调用自己的哪些接口。
现代应用配置核心需求
-
交付件和配置分离
运行期应用根据自身环境到配置中心动态拉取相应的配置
-
抽象标准化
配置管理界面 UI,方便应用开发人员管理和发布配置 封装好的客户端 API,方便应用集成和获取配置
-
多环境多集群
配置中心需要支持对多环境和多集群应用配置的集中式管理
-
高可用
如果配置中心不可用,客户端也需要有降级策略
-
实时性
配置更新需要尽快通知到客户端
-
治理
配置审计,版本控制,配置权限控制,灰度发布
配置中心选型
- zookeeper 早期组件, 现代少见了
- Eureka 早期组件, 现代少见了
- Consul 国外用得较多, 与Vault搭配, 适合多数据中心
- Nacos 大量项目使用
- apollo 大量项目使用
几种配置管理模式
1. 线上为源
优点: 小型项目管理较方便, 适合交付型项目;
配置变更流程:
- 拉取线上当前配置
- 修改配置
- 推送线上, 本地备份+线上备份
- 重启或reload服务
2. 配置中心为源
以配置中心的数据库为准
配置变更流程:
- UI页面修改配置
- 重启或服务自动relaod配置
优点:
- ui友好,方便查看各类配置, 回滚方便
- 配置中心一般提供长轮询或watch机制,能够做到几乎准实时的配置变更速度。
- sdk提供更丰富的配置相关能力。
3. git为源
配置变更流程:
- 本地新分支修改配置
- 提交 Pr
- 评审后合并到对应环境的分支
- 推送到 git 服务器
- CICD工具自动触发线上变更
优点: 充分利用 git 生态, 有较好的版本管理, diff, 评审, 回滚, 审计等功能;
缺点: cicd工具对线上配置变更一般耗时比较多, 链路较长
4. git和配置中心组合方式
- git还是唯一的源, 变更提交pr合并到分支中。
- Git 提交触发 Jenkins 或 GitHub Actions 流水线;
- 流水线调用 Nacos OpenAPI 变更 nacos 配置。
原因是 nacos 长轮询/补丁推送,毫秒级响应,服务配置变更生效速度速度快。
5. Terraform
IaC 基础设施即代码, 虽然它主要用于管理基础设施, 但也有很多企业用来管理配置。
Terraform + git 组合使用;
6. k8s 云原生模式
通过 Helm / Kustomize 加 git 进行管理;
提交后触发 ci/cd 流水线进行环境变更;
7. AWS AppConfig
使用云厂商的配置服务进行管理
推荐的配置管理模式
- git仓库作为唯一配置源, 提供了 diff, 评审, 回滚, 审计等功能
- 密钥通过单独的组件进行管理, 例如 Vault
- 配置变更也需要通过 ci/cd 流程, 避免直接线上修改