配置管理

配置管理

什么是配置: 独立于程序的可配变量。一般根据运行环境需要按需设定。

简述

当前常见配置传递方式

  • 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. 配置散乱格式不标准

  2. 主要采用本地静态配置,配置修改麻烦

  3. 易引发生产事故, 如漏改了1个文件;

  4. 配置缺乏安全审计和版本控制功能

  5. 上下游不解耦,下游变动影响上游:

    例如下游系统在集群中增加了一个ip地址或账号密码, 可能需要多个上游业务系统配合进行配置变更。

  6. 下游服务不知道有多少个上游系统在调用自己的哪些接口。

现代应用配置核心需求

  • 交付件和配置分离

    运行期应用根据自身环境到配置中心动态拉取相应的配置

  • 抽象标准化

    配置管理界面 UI,方便应用开发人员管理和发布配置 封装好的客户端 API,方便应用集成和获取配置

  • 多环境多集群

    配置中心需要支持对多环境和多集群应用配置的集中式管理

  • 高可用

    如果配置中心不可用,客户端也需要有降级策略

  • 实时性

    配置更新需要尽快通知到客户端

  • 治理

    配置审计,版本控制,配置权限控制,灰度发布

配置中心选型

  • zookeeper 早期组件, 现代少见了
  • Eureka 早期组件, 现代少见了
  • Consul 国外用得较多, 与Vault搭配, 适合多数据中心
  • Nacos 大量项目使用
  • apollo 大量项目使用

几种配置管理模式

1. 线上为源

优点: 小型项目管理较方便, 适合交付型项目;

配置变更流程:

  1. 拉取线上当前配置
  2. 修改配置
  3. 推送线上, 本地备份+线上备份
  4. 重启或reload服务

2. 配置中心为源

以配置中心的数据库为准

配置变更流程:

  1. UI页面修改配置
  2. 重启或服务自动relaod配置

优点:

  1. ui友好,方便查看各类配置, 回滚方便
  2. 配置中心一般提供长轮询或watch机制,能够做到几乎准实时的配置变更速度。
  3. sdk提供更丰富的配置相关能力。

3. git为源

配置变更流程:

  1. 本地新分支修改配置
  2. 提交 Pr
  3. 评审后合并到对应环境的分支
  4. 推送到 git 服务器
  5. CICD工具自动触发线上变更

优点: 充分利用 git 生态, 有较好的版本管理, diff, 评审, 回滚, 审计等功能;

缺点: cicd工具对线上配置变更一般耗时比较多, 链路较长

4. git和配置中心组合方式

  1. git还是唯一的源, 变更提交pr合并到分支中。
  2. Git 提交触发 Jenkins 或 GitHub Actions 流水线;
  3. 流水线调用 Nacos OpenAPI 变更 nacos 配置。

原因是 nacos 长轮询/补丁推送,毫秒级响应,服务配置变更生效速度速度快。

5. Terraform

IaC 基础设施即代码, 虽然它主要用于管理基础设施, 但也有很多企业用来管理配置。

Terraform + git 组合使用;

6. k8s 云原生模式

通过 Helm / Kustomize 加 git 进行管理;

提交后触发 ci/cd 流水线进行环境变更;

7. AWS AppConfig

使用云厂商的配置服务进行管理

推荐的配置管理模式

  1. git仓库作为唯一配置源, 提供了 diff, 评审, 回滚, 审计等功能
  2. 密钥通过单独的组件进行管理, 例如 Vault
  3. 配置变更也需要通过 ci/cd 流程, 避免直接线上修改
最后更新于