面试知识库
进阶

Nacos配置中心#

一句话答案#

Nacos Config 通过客户端长轮询(30s)监听配置变更,变更时服务端立即响应,客户端自动刷新本地配置。

核心要点

整体机制:长轮询(Long Polling)

传统轮询:客户端每隔 N 秒拉一次配置 → 实时性差,服务端压力大
长轮询:客户端发请求,服务端 hold 住连接(最多 30s),有变更立即返回

Nacos Config 采用长轮询 + MD5 比对:
  → 客户端发送请求,携带当前配置的 MD5 值
  → 服务端对比 MD5:
     如果相同 → hold 住连接,最多等 29.5s 后返回空(无变更)
     如果不同 → 立即返回变更的 dataId 列表
  → 客户端收到变更的 dataId → 再发 GET 请求拉取最新配置内容
plaintext

详细流程:

客户端关键源码逻辑(ClientWorker):

ClientWorker 内部有两个线程池:
  → 调度线程池(1 个线程):每 10ms 检查是否需要发起长轮询
  → 长轮询线程池(多个线程):执行实际的 HTTP 长轮询请求

流程:
  1. ClientWorker 启动时,为每个监听的 dataId+group 注册 Listener
  2. 调度线程定期检查 → 发起长轮询任务
  3. 长轮询线程向 Nacos Server POST /listener
  4. 收到响应后,拉取变更配置 → 更新本地缓存文件
  5. 触发所有注册的 Listener 回调 → Spring 的 RefreshScope 感知到变更
plaintext

Spring Cloud 集成热刷新的两种方式:

注意事项:

① @RefreshScope 的原理是销毁旧 Bean、创建新 Bean,可能有短暂的空指针
② @ConfigurationProperties 是直接修改属性值,更平滑
③ 配置变更会触发 EnvironmentChangeEvent → 可以监听此事件做额外处理
④ Nacos 客户端会将配置缓存到本地文件 → Nacos Server 宕机后仍可使用缓存
plaintext
面试回答(2分钟版)

Nacos 配置中心的核心机制是长轮询加 MD5 比对。客户端启动后会向 Nacos Server 发起长轮询请求,携带当前配置的 MD5 值。服务端收到后比对 MD5,如果配置没变就挂起连接最多等 29.5 秒后返回空响应;如果配置有变更则立即返回变更的 dataId 列表。客户端收到变更通知后,再发 GET 请求拉取最新配置内容,更新本地缓存并触发 Listener 回调。这样既保证了实时性,又避免了频繁轮询的开销。在 Spring Cloud 中有两种热刷新方式:@Value 配合 @RefreshScope,配置变更时 Bean 会被销毁重建;或者用 @ConfigurationProperties,它是直接修改属性值,更平滑。要注意 @Value 如果不加 @RefreshScope 是不会自动刷新的。另外 Nacos 客户端会把配置缓存到本地文件,即使 Nacos Server 宕机了应用也能正常使用缓存的配置。

追问与易错

追问方向:

  • “变更是推还是拉?”→ Nacos 用长轮询(long polling)机制:客户端发起拉取请求,服务端 hold 住连接(默认 30s),有变更立即返回,兼顾实时性和性能;不是纯推也不是纯轮询
  • “敏感配置怎么处理?”→ 数据库密码、密钥等敏感配置应加密存储:Nacos 支持配置加密插件,也可配合 Jasypt 在客户端解密;生产环境还应控制 Nacos 控制台访问权限,开启鉴权
  • “@RefreshScope 原理?”→ 标注 @RefreshScope 的 Bean 被 Spring 放入特殊 Scope,配置变更时 Spring 销毁旧 Bean 并在下次使用时重新创建(懒加载),从而注入最新配置值;底层通过 RefreshEvent 事件触发

易错点:

  • ❌ 每次读都请求 Nacos——客户端有缓存
  • ❌ @Value 不加 @RefreshScope 也能刷新——不能