springboot配置 之 NacosConfigManager
NacosConfigManager 是 Nacos 客户端(Java SDK)中用于管理配置的核心类,它封装了与 Nacos Server 交互的底层逻辑,提供了获取、监听、发布、删除配置等能力。它是构建在 ConfigService 之上的更高级 API(从 Nacos 2.0+ 开始推荐使用)。
一、核心原理
1. 架构定位
Application
│
▼
NacosConfigManager (入口)
│
▼
ConfigService (核心接口)
│
▼
Client Worker → HTTP/gRPC → Nacos Server
NacosConfigManager是 单例工厂类,用于获取ConfigService实例;- 所有配置操作最终由
ConfigService执行; - 支持 长轮询 + 长连接(gRPC) 实现配置实时推送(Nacos 2.x 默认 gRPC)。
2. 关键机制
| 机制 | 说明 |
|---|---|
| 本地缓存 | 配置拉取后会缓存在本地磁盘(${user.home}/nacos/config),防止服务不可用 |
| 长轮询(1.x) | 客户端定时请求 Server,Server hold 请求直到配置变更 |
| gRPC 推送(2.x) | 建立双向流,Server 主动推送变更,延迟更低 |
| 监听器模型 | 支持注册 Listener,配置变更时回调 |
二、依赖引入(Maven)
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.3.0</version> <!-- 推荐 2.x -->
</dependency>
⚠️ 注意:不要同时引入 Spring Cloud Alibaba Nacos Config,除非你在 Spring 环境中使用。
三、初始化 ConfigService
方式 1:通过 NacosConfigManager(推荐)
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.NacosConfigManager;
import com.alibaba.nacos.api.exception.NacosException;
Properties properties = new Properties();
properties.put("serverAddr", "127.0.0.1:8848"); // Nacos Server 地址
// properties.put("namespace", "your-namespace-id"); // 可选:命名空间
try {
ConfigService configService = NacosConfigManager.createConfigService(properties);
} catch (NacosException e) {
e.printStackTrace();
}
方式 2:直接使用 NacosFactory
ConfigService configService = NacosFactory.createConfigService(properties);
✅
NacosConfigManager内部调用NacosFactory,两者等价。但NacosConfigManager更语义化。
四、四大操作详解(增删查改)
假设配置信息如下:
- Data ID:
app-config.properties - Group:
DEFAULT_GROUP(默认) - Content:
app.name=MyApp server.port=8080
🔹 1. 查(Get Configuration)
String dataId = "app-config.properties";
String group = "DEFAULT_GROUP";
try {
String config = configService.getConfig(dataId, group, 5000); // 超时 5s
System.out.println("配置内容:\n" + config);
} catch (NacosException e) {
System.err.println("获取配置失败: " + e.getMessage());
}
✅ 返回值为
String,需自行解析(如转为Properties)。
🔹 2. 改 / 增(Publish Configuration)
String newContent = """
app.name=UpdatedApp
server.port=9090
""";
try {
boolean isPublishOk = configService.publishConfig(
dataId,
group,
newContent
);
if (isPublishOk) {
System.out.println("配置发布成功");
} else {
System.err.println("配置发布失败");
}
} catch (NacosException e) {
e.printStackTrace();
}
💡 注意:
- 如果配置不存在,则创建新配置;
- 如果存在,则覆盖更新;
- 返回
true表示 Server 接收成功(不保证持久化完成)。
🔹 3. 删(Remove Configuration)
try {
boolean isRemoveOk = configService.removeConfig(dataId, group);
if (isRemoveOk) {
System.out.println("配置删除成功");
} else {
System.err.println("配置删除失败(可能不存在)");
}
} catch (NacosException e) {
e.printStackTrace();
}
⚠️ 删除后,监听该配置的客户端会收到 空内容(null) 的变更通知。
🔹 4. 监听配置变更(Listen)
这是 Nacos 的核心能力!
configService.addListener(dataId, group, new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("【配置变更】新内容:\n" + configInfo);
// 在此处重新加载配置(如刷新 Spring Bean)
}
@Override
public Executor getExecutor() {
// 可指定线程池处理回调(避免阻塞监听线程)
return Executors.newSingleThreadExecutor();
}
});
✅ 特性:
- 启动时会立即触发一次回调(获取当前配置);
- 配置变更后秒级推送;
- 支持多个
Listener。
五、完整示例:动态配置管理器
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.NacosConfigManager;
import com.alibaba.nacos.api.exception.NacosException;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class NacosConfigExample {
private static final String DATA_ID = "app-config.properties";
private static final String GROUP = "DEFAULT_GROUP";
private static ConfigService configService;
public static void main(String[] args) throws NacosException, InterruptedException {
// 1. 初始化 ConfigService
Properties props = new Properties();
props.put("serverAddr", "127.0.0.1:8848");
configService = NacosConfigManager.createConfigService(props);
// 2. 获取当前配置
String currentConfig = configService.getConfig(DATA_ID, GROUP, 3000);
System.out.println("初始配置:\n" + currentConfig);
// 3. 注册监听器
configService.addListener(DATA_ID, GROUP, new com.alibaba.nacos.api.config.listener.Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("\n>>> 配置已更新 <<<");
if (configInfo == null) {
System.out.println("配置已被删除!");
} else {
// 解析新配置
parseConfig(configInfo);
}
}
@Override
public Executor getExecutor() {
return Executors.newCachedThreadPool();
}
});
// 4. 模拟发布新配置(5秒后)
Thread.sleep(5000);
String newConfig = "app.name=DynamicApp\nfeature.enabled=true";
configService.publishConfig(DATA_ID, GROUP, newConfig);
// 5. 保持主线程运行
Thread.currentThread().join();
}
private static void parseConfig(String configStr) {
// 这里可以将字符串转为 Properties 并应用到业务逻辑
System.out.println("解析配置: " + configStr.replace("\n", ", "));
}
}
六、高级特性
1. 命名空间(Namespace)
隔离不同环境(dev/test/prod):
properties.put("namespace", "a1b2c3d4-..."); // 填写命名空间ID(非名称!)
2. 超时与重试
getConfig(timeout)中的 timeout 是首次拉取超时;- 监听器内部有自动重连机制;
- 可通过
properties.put("configLongPollTimeout", "30000")调整长轮询超时。
3. 本地缓存路径
默认缓存位置:
${user.home}/nacos/config
可通过 -DJM.SNAPSHOT.PATH=/custom/path 修改。
4. 权限控制(Nacos 1.2+)
properties.put("username", "nacos");
properties.put("password", "nacos");
七、注意事项与最佳实践
| 问题 | 建议 |
|---|---|
| 配置过大 | 单个配置建议 < 100KB,避免内存溢出 |
| 频繁变更 | 监听器回调中避免耗时操作(用独立线程池) |
| 中文乱码 | Nacos Server 和 Client 均使用 UTF-8,一般无问题 |
| 生产环境 | 使用 VIP 或集群地址(如 192.168.1.10:8848,192.168.1.11:8848) |
| Spring 集成 | 优先使用 @RefreshScope + @Value,而非手动监听 |
八、常见异常
| 异常 | 原因 |
|---|---|
NacosException: client not connected |
Nacos Server 不可达 |
NacosException: config data not exist |
Data ID + Group 不存在 |
SocketTimeoutException |
网络超时,检查防火墙/端口 |
总结
NacosConfigManager(实际是 ConfigService)提供了简洁的 API 实现配置的 增删查改 + 实时监听:
| 操作 | 方法 |
|---|---|
| 查 | getConfig(dataId, group, timeout) |
| 增/改 | publishConfig(dataId, group, content) |
| 删 | removeConfig(dataId, group) |
| 监听 | addListener(dataId, group, listener) |
✅ 核心价值:
解耦配置与代码,实现配置热更新,无需重启服务。
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/19502269

浙公网安备 33010602011771号