瑞典马工

配置管理:被忽视的技术债务

问一个问题:你的团队怎么管理配置?

如果答案是"放数据库"、"用.env文件"、"有个Apollo配置中心",那再问一个问题:谁来更新配置?怎么审计?出错了怎么回滚?

大概率,没人能给出清晰答案。

我过去两个月逐步移除了项目中的.env文件,就是因为看不下去这种乱象。而且我发现,行业里根本没有公认的配置管理最佳实践。Apollo、Nacos、AWS Parameter Store、LaunchDarkly —— 每个工具解决局部问题,但没人给出完整的方法论。

这篇文章不是要推销某个工具,也不是说我找到了完美方案。恰恰相反,我想说的是:配置管理这个问题,行业还没想清楚。

多个Sources of Truth

配置管理的第一个问题:太多sources of truth。

拿Ruby on Rails项目来说。你看到代码里写config.timeout = 30,但实际运行时可能是60(.env里override了),也可能是90(数据库里又override了),还可能真的是30(代码默认值)。你看到代码或者配置还不够,你要脑袋里跑一遍,才知道究竟它用的是哪个配置。

更麻烦的是业务配置。比如针对荷兰市场的在线娱乐行业,有专门的关键词列表,可能一个月变动一次。这种配置,放数据库?配置文件?还是硬编码?谁来更新?PM不会登录AWS Console,也不会写SQL。数据库里的配置表,出问题了要去生产环境看,审计也不好做,不容易搞清楚谁什么时候做了什么修改。

问题是:没人能给出明确答案。问10个工程师,能得到5种不同方案:

  • 用Apollo配置中心
  • 放AWS Parameter Store
  • 写到数据库配置表
  • 硬编码到代码里
  • 用LaunchDarkly的feature flags

每种方案都有人用,每种方案都有问题。

.env的问题:前云时代的遗留思维

很多团队依赖.env文件管理配置。这来自12-Factor App的推荐:用环境变量存配置。2011年Heroku提出这个原则时,确实是进步 —— 相比hardcode到代码里,环境变量至少能区分开发和生产环境。

但现在是2025年了。.env有两个致命问题。

第一是一致性。.env天然是host scope的。你在开发机上有个.env,测试服务器上有另一个.env,生产服务器上又是一个.env。这就意味着,测试环境可能有生产环境的配置,非常危险。反过来也是,生产环境有测试配置,运维一不小心,就把两个环境搞反了。

第二是安全性。你不应该把credentials放到.env。但很多团队就这么干。结果是.env文件被commit到git(虽然有.gitignore,但总有人忘记),或者通过Slack、email传来传去。更糟的是,.env通过/proc文件系统暴露给任何进程,任何能读/proc的人都能看到你的密钥。

更根本的问题是:.env解决的是2011年的问题。那时候没有Infrastructure as Code,没有Docker,环境不一致很常见。配置不齐全,用默认值fallback,至少能让服务器跑起来,不至于浪费CPU。

但现在有了Docker和IaC,保证环境一致性很容易了。如果有配置项消失了,那肯定是个bug,直接fail fast就好了。默认值和fallback机制,是前云时代的遗留思维。

AWS Parameter Store:解决了错误的问题

有人会说:AWS Parameter Store不就是解决这些问题的吗?

确实,Parameter Store解决了一些问题:密钥加密、IAM权限控制、区分环境。但它没解决更重要的问题。

第一,谁来更新?PM不会用AWS Console,也不应该给他们生产环境的IAM权限。工程师手动更新?那怎么审计?怎么知道谁什么时候改了什么配置?Parameter Store的版本历史很弱,看不到business context,只能看到"parameter updated"。

第二,lifecycle management。荷兰市场的关键词列表,一个月更新一次。谁负责更新?用什么流程?出错了怎么回滚?Parameter Store不管这些,它只是个key-value store。

第三,成本。Parameter Store标准版免费,但有限制(10000个参数,4KB大小)。高级版按API调用收费。规模上来后,成本不低。

更致命的是凭证轮换的时间窗口问题。Parameter Store支持自动轮换,听起来很好。但实际上:Terraform生成新的数据库密码,写入/svc/payment/database_password,旧密码立刻失效。问题是,15个微服务还没重启,还在用旧密码连接数据库。生产环境挂了2-5分钟,直到所有服务重启完成。

为什么?因为传统数据库不支持dual-password grace period(双密码过渡期)。云原生工具假设你的基础设施也是云原生的,但现实是很多公司跑的是混合架构:云原生应用 + 传统数据库。结果就是,理论上的自动轮换,实践中团队都禁用了,还是手动协调更新。

Apollo/Nacos:笨重版本的Parameter Store

国内很多团队用Apollo或Nacos配置中心。说实话,这些工具就是笨重版本的Parameter Store。

它们解决了什么?配置托管,访问控制,多环境管理。但这个问题太简单了。Parameter Store也能做,而且不需要你自己维护服务。

Apollo和Nacos都需要运维团队维护。要部署配置中心服务,要保证高可用,要升级版本。而且我看了下,Apollo都不支持自定义加密密钥,只能用它默认的加密方式。这对于有合规要求的团队来说,根本不够。

更关键的是,Apollo和Nacos仍然没解决配置管理的核心问题:谁来更新?如何审计?lifecycle怎么管理?它们只是把配置从.env或数据库搬到了另一个地方,换汤不换药。

我看过一些团队的做法:PM在Slack上发消息,"帮我把荷兰市场的关键词列表更新一下",然后工程师登录Apollo后台,手动修改配置,点击发布。这跟直接改数据库有什么本质区别?都是手工操作,都没有code review,都没有完整的audit trail。

LaunchDarkly:解决的是另一个问题

有人会推荐LaunchDarkly。先说清楚:LaunchDarkly是好产品,但它解决的是另一个问题。

Feature flags是用来做动态实验切换的:A/B测试,灰度发布,紧急kill switch。你需要实时改变某个功能的开关状态,不需要重新部署。这是LaunchDarkly擅长的。

但业务配置不是这样。荷兰市场的关键词列表,一个月才变动一次。这是静态数据,不需要实时切换,不需要按百分比灰度。用LaunchDarkly管理这种配置,就像用法拉利去买菜 —— 能用,但太贵,也没必要。

LaunchDarkly的企业版,50个用户起步,一年要$70,000以上(数据来源:https://www.featbit.co/articles2025/why-launchdarkly-remains-expensive-2025)。花这个钱去管理一个月更新一次的关键词列表?

行业混淆了feature flags和configuration management。Feature flags是运行时的动态开关,configuration management是配置的全生命周期管理。这是两个不同的问题,需要不同的工具。

核心问题:方法论的缺失

说了这么多工具的问题,根本原因是什么?

我发现,行业里没有靠谱的配置管理框架,都是些零零碎碎的工具或者心得。每个工具解决一个局部问题(托管、加密、访问控制),但真正有挑战的问题是把配置的整个生命周期考虑进来,低成本地解决。这里的低成本,不只是硬件成本,更多的是时间成本 —— 工程师debug配置的时间,PM更新配置的流程,团队协作的摩擦。

配置需要分类。不同类型的配置,需要不同的管理方式。但行业没有给出系统性的分类框架。

我试着总结了几个维度:

  • IT配置 vs 业务配置
    :数据库连接字符串 vs 市场规则关键词列表
  • Credential vs 非加密配置
    :API密钥 vs 超时时间
  • 频繁变动 vs 非频繁变动
    :每天调整 vs 季度更新
  • 生产环境 vs 测试环境
    :不能混淆
  • 必要配置 vs 可选配置
    :缺失时fail fast vs 有默认值
  • 服务独享 vs 共享配置
    :单个服务 vs 多服务依赖

针对不同的组合,需要回答这些问题:

  1. 谁来更新
    ?PM、工程师、还是自动化流程?
  2. 用什么更新
    ?PR、后台界面、还是API?
  3. 存在哪里
    ?Git、数据库、Parameter Store、还是配置中心?
  4. 如何传播
    ?服务重启、热加载、还是订阅推送?
  5. 如何保证一致性
    ?多个服务如何同步配置?
  6. 如何保证安全
    ?谁有权限查看和修改?

但行业没有给出系统性的答案。大家都在凭感觉做决定,然后踩坑,然后重构。

一个局部方案:GitOps for Business Config

我不敢说找到了完美方案,但至少对于业务配置,我找到了一个可行的做法:把配置当代码管理。

具体来说:

  • 配置硬编码到codebase
  • PM通过PR更新配置
  • CI/CD自动发布,应用新配置
  • Git提供审计trail

这就是GitOps (https://about.gitlab.com/topics/gitops/) 原则在应用配置上的应用。GitOps原本是用于基础设施管理的,但同样适用于业务配置。

举个例子,荷兰市场的关键词列表:

# config/market_rules.py
NETHERLANDS_BLOCKED_KEYWORDS = [
"casino",
"gambling",
# ...
]

一个月后,PM需要更新列表。他创建一个PR,添加新关键词,工程师review,merge后CI/CD自动部署。整个过程有完整的git history,可以看到谁在什么时候改了什么,为什么改。

这个方案的适用范围:

  • ✅ 业务配置:关键词列表、市场规则、定价策略
  • ✅ 非频繁变动:月度、季度更新的配置
  • ✅ 需要审计:合规要求记录所有变更
  • ✅ PM参与:PM会用git,或者至少能提供文本文件

这个方案不适用:

  • ❌ Credentials:应该用secret manager,不能commit到git
  • ❌ 实时feature flags:应该用LaunchDarkly这类工具
  • ❌ 基础设施配置:应该用Terraform/IaC
  • ❌ 频繁变动的配置:每天调整几次的,用数据库或配置中心

重点是:这不是银弹。它只解决了配置管理问题的一小部分。但这一小部分很重要,而且被大多数团队忽视了。

AI时代让配置问题更紧迫

上周五我遇到个典型案例。遗留系统的配置散落在4个地方,即使给Claude Code配好了AWS profile,它也被搞晕了,反复用"likely"这个词:"This setting is likely coming from..."。连AI都猜不准配置从哪里来。

当配置散落在.env、数据库、代码默认值、YAML文件多个地方,AI很难判断优先级。它只能说"likely",因为它不确定runtime时哪个配置会生效。这种隐式的覆盖逻辑,AI处理不好,人类也容易出错。

AI时代,配置混乱的代价放大了:

  • AI编码速度快10倍
    ,配置错误传播也快10倍
  • AI无法处理隐式逻辑
    ,Rails的Convention over Configuration对AI是噩梦
  • AI会泄露凭证
    ,如果配置管理不规范,AI可能把.env的内容写进代码或commit历史

解决方案是:配置要AI友好。单一数据源,明确的优先级,fail fast而不是fallback。GitOps天然AI友好:配置在git里,明确、可追溯、有完整历史。

说句难听的,如果你的配置管理连AI都搞不懂,那人类也早晚会犯错。

我们需要行业共识

配置管理是被忽视的技术债务。我们自动化了CI/CD,自动化了基础设施,却在配置管理上还用手工作坊方法。

现有工具各自解决局部问题:Apollo托管配置,Parameter Store加密存储,LaunchDarkly管理feature flags。但没有人给出配置管理的完整方法论。

我提出的GitOps方案,只是拼图的一小块。它适用于业务配置,但不适用于credentials或实时feature flags。行业需要建立配置管理的分类框架,针对不同类型的配置,给出系统性的答案。

有兴趣研究这个问题的同好,欢迎在公众号给我留言,我们一起交流讨论。