Nacos Config 配置中心如何工作?动态刷新配置的原理是什么?
结论先行:Nacos Config 把配置从“文件打包进 jar”升级为“中心化存储 + 运行时下发”。客户端启动拉取配置建立本地缓存,之后通过长轮询/服务端推送感知变更:收到变更 → 客户端刷新 Environment → 触发 RefreshScope 重建 Bean / 重新绑定 @ConfigurationProperties,实现不停机改配置。
一、接入方式
spring:
config:
import: nacos:order-service.yaml # 导入配置(Boot 2.4+/SCA 新写法)
cloud:
nacos:
config:
server-addr: nacos-host:8848
file-extension: yaml # 默认 properties
group: DEFAULT_GROUP
namespace: prod # 环境/租户隔离
- dataId 默认规则:
${spring.application.name}.${file-extension},支持 profile 维度${name}-${profile}.yaml; - namespace 隔离环境,group 隔离业务线,三者组合唯一定位一份配置;
- 优先级:
${name}-${profile}>${name}> 应用本地配置(本地更低,可做兜底)。
二、动态刷新原理
| 环节 | 机制 |
|---|---|
| 启动拉取 | 客户端启动时拉取配置生成 PropertySource |
| 变更感知 | 客户端对 dataId 建立监听(长轮询),服务端配置变更即响应 |
| 事件发布 | 收到变更发布 RefreshEvent / 环境变更事件 |
| Bean 重建 | @RefreshScope 的 Bean 销毁重建;@ConfigurationProperties 重新绑定 |
| 生效范围 | 普通 @Value 默认不刷新,需 @RefreshScope 包裹 |
@Component
@RefreshScope // 刷新时重建本 Bean
public class DynamicProps {
@Value("${order.timeout:3000}")
private int timeout;
}
- 局限:刷新对“已持有旧 Bean 的调用方”不实时(重建的是新请求拿到的实例);
- 不适合刷新项:线程池配置、连接池(需重建资源)等应评估是否支持运行时变更;
- 发布规范:改配置前先备份、小步灰度(多 namespace/group),变更后观察日志与指标。
三、为何比本地配置强
- 一处修改、全集群生效,杜绝“每台机器手改配置文件”;
- 环境隔离 + 审计 + 回滚(Nacos 控制台支持历史版本);
- 与注册中心同源运维,减少一套中间件。
常见追问 / 记忆点
- 追问:@Value 为什么不自动刷新?答:@Value 在 Bean 创建时固化,属性和 Bean 生命周期绑定,需 @RefreshScope 让 Bean 重建。
- 追问:配置中心挂了应用还能启动吗?答:配置中心宕机时可用本地缓存/本地文件兜底启动,但改不了配置。
- 记忆点:导入→监听→刷 Environment→重建 @RefreshScope Bean;刷新面靠 @ConfigurationProperties/@RefreshScope 控制。