【spring boot】[nacos] ----一篇文章搞懂 nacos 底层动态刷新配置原理超详细 - 指南

【总结】

30秒长轮询+@RefreshScope重新加载bean
在这里插入图片描述

(有数据更新)

1、客户端每隔30秒发送一次长轮询(http)
2、若是有变更,返回元材料,客户端拿到元数据会再次请求yml单个文件全内容。
3、客户端触发发更新。

(无材料更新)

1、客户端每隔30秒发送一次长轮询(http)
2、没有信息更新,服务器会把请求堵塞30秒后返回空响应。
3、客户端触发发更新。

一、为什么 Nacos 能构建动态刷新配置(无需重启服务)?

传统的 Java 服务配置通常写在本地文档(如application.properties)中,服务启动时会一次性读取这些设置并加载到内存,之后不再主动读取文档。因此,配置变更后必须重启服务才能生效。
而 Nacos 的核心能力之一是「动态配置管理」:服务启动后,Nacos 客户端会持续监听安装中心的变更,一旦安装更新,客户端会自动获取新调整并触发应用内部的刷新逻辑,无需重启服务。
这种能力的本质是:将部署从「本地静态加载」变为「远程动态监听 + 内存实时更新」。

二、动态刷新的底层原理

Nacos 的动态配置刷新依赖「客户端 - 服务端协同机制」和「应用内配置更新逻辑」,核心流程分为 3 步:

1. 客户端与服务端的「长轮询」通信

Nacos 客户端(嵌入在 Java 服务中)会利用「长轮询(Long Polling)」机制与 Nacos 服务端保持通信,实时感知安装变更。

  • 客户端发送一个请求后,服务端会「hold 住这个请求」(最长 30 秒):就是长轮询不是频繁的短轮询(避免浪费资源),而
  • 如果期间配置没有变更,服务端会在 30 秒后返回空响应,客户端收到后立即发起下一次长轮询;
  • 若是期间配置发生变更,服务端会立即返回变更的配置信息,客户端无需等待。
  • 这种机制既保证了部署变更的实时性(秒级),又减少了无效请求(相比短轮询,请求量降低 90% 以上)。

2. 设置变更的「监听与通知」

Nacos 客户端会提前注册「配置监听器」,当通过长轮询感知到配置变更后:

  • 客户端会从服务端拉取完整的新配置(而非仅变更部分),并更新本地缓存(内存 + 本地文件备份,防止服务端宕机);
  • 触发监听器的回调函数,通知应用「配置已变更」。

3. 应用内部的「配置生效」

应用收到配置变更通知后,要求将新配置应用到运行中的组件。这一步通常依赖框架(如 Spring Cloud)的支持:

  • 以 Spring Cloud 为例,通过@RefreshScope注解标记的 Bean,在配置变更时会被「销毁并重新创建」,新创建的 Bean 会读取最新的配置值;
  • 对于未标记@RefreshScope的 Bean(如单例 Bean),如果需动态刷新,需手动编写逻辑(如监听配置变更事件,主动更新 Bean 的属性)。

三、应用场景

并非所有配置都适合动态刷新,通常承受的是「无状态、可热更新」的设置,主要包括:
1.应用参数: 各种开关、阈值、超时时间、重试次数、功能标识等 (e.g., feature.enabled=true, order.timeout=5000)。
2.业务规则: 费率、折扣、活动规则、文案内容等。
3.连接信息 (需谨慎): Redis、MQ 的地址和端口(注意:动态修改这些可能导致连接中断,需要应用有重连机制)。
4.线程池参数: 核心线程数、最大线程数、队列大小等 (e.g., thread.pool.core-size=10)。
通过5.日志级别: 动态调整不同包的日志级别 (e.g., logging.level.com.example=DEBUG),Spring Boot 本身承受通过 Actuator 或 Logback 的监听机制构建,结合 Nacos 能够统一管理。
6.路由规则: 在微服务中常用于灰度发布、A/B 测试的动态路由配置。

四、注意

如果动态改redis、mysql等连接可能会出现有人在用接口,出现短暂的错误。
如果改线程池。
----正在执行的任务: 不会被强制杀掉。它们会被允许继续执行直到正常完成(除非任务本身响应中断)。
-----队列中的任务: 不会被立即丢弃。它们会在旧线程池关闭过程中,被旧线程池中未被中断的线程继续执行完。

posted @ 2025-08-08 12:03  yjbjingcha  阅读(243)  评论(0)    收藏  举报