Nacos 配置中心
This content is not available in your language yet.
单体应用里,配置跟着代码一起发布。进入多环境、多实例部署后,数据库地址、功能开关、限流阈值等配置必须独立管理。
配置中心不只是”把配置存到另一台服务器”,还要解决多环境隔离、秒级发布、动态推送和故障回退。
准备依赖与基础配置
Section titled “准备依赖与基础配置”Feat Cloud 没有内置 Nacos starter。 本文直接使用官方 nacos-client,不额外封装。多写几十行胶水代码,换来的是完全透明的链路——连接在哪建立、配置在哪回调、坏配置为什么被拦截,全部一目了然。
引入 Nacos 客户端
Section titled “引入 Nacos 客户端”在已有 Feat Cloud 应用基础上,加上 nacos-client:
<dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>3.2.3</version></dependency>nacos-client 是运行期依赖,feat-cloud-starter 仍然负责编译期生成代码。两者各管各的,互不替代。
在 feat.yml 里声明连接信息
Section titled “在 feat.yml 里声明连接信息”Nacos 服务地址、namespace、鉴权信息这类”环境之间会变、但启动后不变”的参数,放进 feat.yml 最合适。
nacos: serverAddr: 127.0.0.1:8848 namespace: public username: nacos password: nacos这些值会在编译期通过 @Value 解析并注入到字段里。因为 @Value 只支持 String、int、String[]、List<String> 等少量类型,所以 Nacos 连接参数统一用字符串声明最省事。
按环境拆分 Nacos 连接
Section titled “按环境拆分 Nacos 连接”本地开发连本机 Nacos,测试环境连测试集群,生产环境连生产集群。这是典型的 Profile 场景。
nacos: serverAddr: dev-nacos.example.com:8848 namespace: devnacos: serverAddr: prod-nacos.example.com:8848 namespace: prod不同环境各有一套 FeatApplication* 生成类,启动时通过 feat.profiles.active 选择:
java -Dfeat.profiles.active=prod -jar yourapp.jar配置中心接入
Section titled “配置中心接入”配置中心最核心的需求不是”能读到配置”,而是”配置变更时应用能安全地用上新值”。下面用一个类完成连接、拉取和监听,保持最小结构。
一个类搞定配置中心
Section titled “一个类搞定配置中心”package com.example.nacos.config;
import com.alibaba.nacos.api.NacosFactory;import com.alibaba.nacos.api.PropertyKeyConst;import com.alibaba.nacos.api.config.ConfigService;import com.alibaba.nacos.api.config.listener.Listener;import tech.smartboot.feat.cloud.annotation.*;
import java.util.Properties;import java.util.concurrent.Executor;
@Bean(order = 0)public class NacosConfigService {
@Value("${nacos.serverAddr}") private String serverAddr;
@Value("${nacos.namespace:public}") private String namespace;
@Value("${nacos.username:}") private String username;
@Value("${nacos.password:}") private String password;
private static final String DATA_ID = "demo-config"; private static final String GROUP = "feat";
private ConfigService configService; private String config;
@PostConstruct public void init() throws Exception { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); properties.put(PropertyKeyConst.NAMESPACE, namespace); if (username != null && !username.isEmpty()) { properties.put(PropertyKeyConst.USERNAME, username); properties.put(PropertyKeyConst.PASSWORD, password); } configService = NacosFactory.createConfigService(properties);
// 一次调用完成"拉取初始配置 + 注册监听器",避免拉取与注册之间的空窗期 config = configService.getConfigAndSignListener(DATA_ID, GROUP, 3000, new Listener() { @Override public Executor getExecutor() { return null; }
@Override public void receiveConfigInfo(String configInfo) { if (configInfo != null) { config = configInfo; } } }); }
public String getConfig() { return config; }
@PreDestroy public void close() throws Exception { if (configService != null) { configService.shutDown(); } }
// setter public void setServerAddr(String serverAddr) { this.serverAddr = serverAddr; } public void setNamespace(String namespace) { this.namespace = namespace; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; }}这段代码做了四件事:
- 建立连接:用
nacos.serverAddr等参数创建ConfigService - 拉取 + 监听:通过
getConfigAndSignListener一次调用拿到初始值并注册监听器,省去先getConfig再addListener的两步操作,也避免两者之间的空窗期 - 优雅关闭:应用停机时断开长连接
在 Controller 里验证
Section titled “在 Controller 里验证”写一个简单的接口,验证配置能读到、刷新也生效。
package com.example.nacos.controller;
import com.example.nacos.config.NacosConfigService;import tech.smartboot.feat.cloud.RestResult;import tech.smartboot.feat.cloud.annotation.*;
@Controller("config")public class DemoController {
@Autowired private NacosConfigService nacosConfigService;
@RequestMapping("/current") public RestResult<String> current() { return RestResult.ok(nacosConfigService.getConfig()); }}启动应用后:
curl http://localhost:8080/config/current然后去 Nacos 控制台修改 demo-config / feat 这个配置的内容,稍等片刻再请求一次,应该能看到新值。
生产环境注意事项
Section titled “生产环境注意事项”上线前记住三件事就够了:
- 开鉴权:Nacos 服务端开启鉴权,口令不要写死在仓库里
- 先校验再刷新:监听到新配置后先检查格式和必填字段,坏配置不要覆盖内存值
- 先初始化基础设施:
NacosConfigService这种 Bean 的order设为0,让它先于默认 Bean 初始化
这三条基本就覆盖了大多数生产问题。
一条可验证的完整链路
Section titled “一条可验证的完整链路”把上面的代码拼起来,你应该能验证下面这条链路:
Nacos 配置中心 -> NacosConfigService -> DemoController -> /config/current可以用这些命令验证:
curl http://localhost:8080/config/current# 修改 Nacos 里的 demo-config / feat,等待 1-3 秒后再请求curl http://localhost:8080/config/current如果两次请求分别返回修改前后的配置内容,说明 Nacos 配置中心已经成功接入了。
Feat 不包一层 starter,也不重写配置中心。Nacos 的 ConfigService、Listener、长轮询全是官方原生的东西;Feat 只负责把它接进生命周期:编译期注入、启动时初始化、停机时释放。
多写几十行胶水代码,换来的是每一行都看得见——连接在哪建立、配置在哪回调、坏配置为什么被拦截。排查线上问题时,你能立刻定位是 Feat 的生命周期、Nacos 客户端,还是配置内容本身出了问题。
接 Sentinel、Redis、RocketMQ 时,套路一样:依赖 + @Value + @PostConstruct + @PreDestroy,中间按官方文档来。