半夜换数据库密码
安全扫描发现数据库弱密码,要全局换一遍。密码写在几十个服务的配置文件里——改配置、提发版、等窗口、全量回归,一个密码换了三天。老王合上电脑说了一句:配置跟着代码走发布,是这个系统发版慢的一半原因。
配置和代码的变更节奏本来就不同:代码跟着需求走,一周一个版本;配置跟着环境、运维和运营走,说改就得改。节奏不同的东西绑在一起发布,慢的拖快的,危险的连累安全的。
哪些配置该进配置中心
不是所有配置都要搬,判断标准是变更时是否要求代码重新构建:环境地址、线程池大小、降级开关、业务参数——这些变更不该触发构建,进配置中心;框架结构性配置的变更必然伴随代码,留在工程里更直观。密钥类单独对待:进配置中心比进代码仓库好,最好再套一层加密或密钥管理服务。
| 配置类别 | 例子 | 变更频率 | 归宿 |
|---|---|---|---|
| 环境相关 | DB 地址、第三方域名 | 低 | 配置中心,按环境隔离 |
| 运维开关 | 降级开关、日志级别 | 中高 | 配置中心,动态刷新 |
| 业务参数 | 活动阈值、风控规则 | 高 | 配置中心,灰度发布 |
| 结构装配 | Bean 装配参数 | 随代码 | 工程内配置文件 |
动态刷新为什么能做到秒级
配置同步不是靠死轮询(间隔长了生效慢,短了压力大),主流方案是长轮询:客户端发起请求后,服务端不立即返回,挂住最多 30 秒;期间配置有变更立即返回,没有则超时空返回。既有接近推送的实时性,又避免了纯推送的连接维护成本。Nacos 客户端对每个配置项维持长轮询,变更到达后本地触发刷新事件。
Spring 侧的刷新机制要分清:@RefreshScope 标记的 Bean 在配置变更时销毁重建,下次访问拿新值;没标 Scope 的单例 Bean 里 @Value 注入的值是启动时绑定的,配置改了它也不会变——这是"为什么我改了配置不生效"的第一大原因。
@RefreshScope
@Component
public class RateLimitProps {
@Value("${limit.qps:100}") // Bean 重建后拿到新值
private int qps;
}
// 没加 @RefreshScope 的 Bean:qps 永远是启动时的值
// 动态配置建议走 ConfigurationProperties + RefreshScope
// 或自行监听 EnvironmentChangeEvent 做定向刷新刷新的几个坑
动态刷新有三类经典翻车:一是启动时序——配置中心连不上时应用起不起来,要设计好降级(本地兜底配置加重试);二是状态丢失——@RefreshScope 重建 Bean 会丢状态,连接池这类有状态组件别走动态刷新;三是半新半旧——多实例刷新有先后,刷新窗口内请求可能打到不同配置的实例上,对一致性敏感的变更要用开关式设计:先加开关、灰度切行为、确认后再清理。
配置也是生产变更
配置中心把发布从"构建-回归-上线"简化成"改一下秒级生效"——效率提升的另一面是变更更容易,出事也更快。生产配置的每一次变更都是一次发布:要有环境隔离、变更审计、一键回滚,重要配置要有灰度。下一篇就讲这套配置的发布纪律:灰度、审计与回滚。
评论 (0)