Spring Cloud Nacos 配置中心详解:从基础使用到 MyBatis 整合(含多文档配置)
Spring Cloud Nacos 配置中心详解:从基础使用到 MyBatis 整合(含多文档配置)
结合我们之前学的 Nacos 服务注册、Sentinel 熔断等知识,今天聚焦Nacos 配置中心—— 它解决了微服务架构中 “配置分散、环境难区分、无法实时更新” 的核心痛点。本文会从 “为什么需要配置中心” 切入,详细拆解yml 配置与 Nacos 的对应关系(重点)、分类配置方案,再补充 MyBatis 整合的两种连接池方式(德鲁伊 + 自定义),以及 yml 多文档写法,帮我们建立 “配置统一管理” 的完整认知。
1. 先懂核心痛点:为什么需要 Nacos 配置中心?
在没使用配置中心前,我们的微服务配置存在 3 个致命问题,这也是 Nacos 配置中心的核心价值所在:
痛点 | 我们的实际困扰 | Nacos 的解决方案 |
---|---|---|
配置分散 | 每个微服务都有自己的application.yml ,10 个服务就要改 10 个配置文件,管理混乱 | 所有配置统一存放在 Nacos,微服务按需拉取,一个地方改全服务生效 |
环境难区分 | 开发、测试、生产环境的数据库地址不同,每次部署要手动改配置,容易出错 | 用 “命名空间 / Group/DataId” 区分环境,启动时指定环境即可,无需改配置文件 |
无法实时更新 | 改了配置(如缓存超时时间),必须重启微服务才能生效,影响线上服务可用性 | 配置修改后 Nacos 主动推送给微服务,配合@RefreshScope 注解实现实时生效,无需重启 |
生活类比:Nacos 配置中心就像 “公司的行政部”—— 所有员工的考勤规则、福利政策(对应配置)都由行政部统一制定(Nacos 存储),员工(微服务)不用自己记规则,规则更新时行政部会主动通知(实时推送),不用员工重新入职(重启)。
2. Nacos Config 基础使用:从项目搭建到配置拉取
我们先从基础流程入手,新建ConfigCenter
子项目,实现 “从 Nacos 拉取配置”,重点理解yml 配置与 Nacos DataId 的对应关系(核心)。
2.1 步骤 1:新建 ConfigCenter 子项目(父项目下)
父项目右键→New→Module→Maven,项目名:
ConfigCenter
;核心是配置
pom.xml
,引入 Nacos 配置中心、服务发现、bootstrap 依赖(新版本必需)。
2.2 步骤 2:配置 pom.xml(关键依赖)
<dependencies><!-- 1. Nacos服务发现依赖(可选,若需注册到Nacos) --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- 2. Nacos配置中心核心依赖(必需) --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- 3. Bootstrap依赖(必需!新版本Spring Cloud移除了bootstrap,需手动引入) --><!-- 作用:保证项目启动时先拉取Nacos配置,再加载application.yml --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><!-- 4. Web依赖(用于测试接口) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 5. FastJSON依赖(返回JSON响应) --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.14</version></dependency></dependencies>
我们的关键提醒:spring-cloud-starter-bootstrap
绝对不能少!因为 Spring Boot 加载配置的优先级是:bootstrap.yml > application.yml
,而 Nacos 配置需要在项目启动初期拉取(否则项目可能因缺少配置启动失败),bootstrap.yml
正是负责 “启动初期拉取 Nacos 配置” 的核心。
2.3 步骤 3:配置 yml 文件(bootstrap.yml + application.yml)
这是最核心的一步 ——bootstrap.yml
配置 Nacos 连接信息,决定从 Nacos 拉取哪个配置;application.yml
可放本地补充配置(优先级低于 Nacos 配置)。
2.3.1 bootstrap.yml(核心:配置 Nacos 拉取规则)
spring:application:# 1. 服务名(对应Nacos DataId的prefix部分,默认值)name: config-centerprofiles:# 2. 当前环境(对应Nacos DataId的spring.profiles.active部分)# 启动时可通过-Dspring.profiles.active=test切换环境active: devcloud:nacos:# Nacos服务注册配置(可选,若需注册到Nacos)discovery:server-addr: 127.0.0.1:8848 # Nacos地址(和注册中心一致)# Nacos配置中心核心配置(必需)config:server-addr: 127.0.0.1:8848 # Nacos配置中心地址(和注册中心一致)file-extension: yaml # 3. 配置文件类型(对应Nacos DataId的file-extension部分)# group: DEFAULT_GROUP # 可选,默认DEFAULT_GROUP,后续分类配置会用到# namespace: 760ae4af-1a85-41c7-9db2-44dd58f3f95e # 可选,默认public,后续分类配置会用到
2.3.2 application.yml(本地补充配置,可选)
# 本地配置(优先级低于Nacos配置,Nacos配置会覆盖此处相同配置)# 一般放无需动态更新的本地配置,如日志级别logging:level:root: infocom.zh.configcenter: debug
2.4 步骤 4:理解 Nacos DataId 与 yml 的对应关系(重点!)
Nacos 通过DataId唯一标识一个配置文件,其命名规则是:${prefix}-${spring.profiles.active}.${file-extension}
我们用表格明确每个部分与bootstrap.yml
的对应关系:
DataId 组成部分 | 对应 bootstrap.yml 配置项 | 示例值 | 说明 |
---|---|---|---|
prefix | spring.application.name | config-center | 默认是服务名,也可通过spring.cloud.nacos.config.prefix 自定义 |
spring.profiles.active | spring.profiles.active | dev | 当前环境,若为空,DataId 格式变为${prefix}.${file-extension} |
file-extension | spring.cloud.nacos.config.file-extension | yaml | 配置文件类型,仅支持yaml 和properties |
我们的示例对应:根据上面的bootstrap.yml
,DataId 最终为:config-center-dev.yaml
—— 这是我们后续在 Nacos 中创建配置的 “唯一标识”,必须完全一致!
2.5 步骤 5:在 Nacos 创建配置文件
访问 Nacos 控制台→配置管理→配置列表→新建配置;
按以下信息填写(严格对应 DataId 规则):
Data ID:
config-center-dev.yaml
(和我们计算的一致);Group:
DEFAULT_GROUP
(默认,和 bootstrap.yml 一致);配置格式:
YAML
(和 file-extension 一致);配置内容(示例:自定义一个配置项):
config:info: "我是从Nacos配置中心拉取的dev环境配置!" # 自定义配置项,后续测试用
点击 “发布”,配置保存到 Nacos。
2.6 步骤 6:测试配置拉取与动态更新
6.1 编写测试 Controller(含动态刷新)
package com.lh.configcenter.controller;import com.alibaba.fastjson.JSONObject;import org.springframework.beans.factory.annotation.Value;import org.springframework.cloud.context.config.annotation.RefreshScope;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;// 关键:@RefreshScope 开启Nacos配置动态刷新(配置修改后无需重启,实时生效)@RefreshScope@RestControllerpublic class ConfigCenterController {// 从Nacos配置中取值:${config.info}对应Nacos中的config.info@Value("${config.info}")private String configInfo;// 测试接口:返回Nacos拉取的配置@GetMapping("/configInfo")@ResponseBodypublic JSONObject getConfigInfo() {JSONObject ret = new JSONObject();ret.put("code", 0);ret.put("message", "配置拉取成功");ret.put("data", configInfo); // 返回Nacos中的config.inforeturn ret;}}
6.2 启动项目测试
启动
ConfigCenterApplication
(主类加@SpringBootApplication
和@EnableDiscoveryClient
);访问接口:
http://localhost:8080/configInfo
(默认端口,若 Nacos 配置了 server.port 会覆盖);预期响应:
{"code": 0,"message": "配置拉取成功","data": "我是从Nacos配置中心拉取的dev环境配置!"}
6.3 测试动态更新
回到 Nacos 控制台,编辑
config-center-dev.yaml
,修改config.info
为:"我是Nacos修改后的dev配置!"
;点击 “发布”,无需重启
ConfigCenter
;再次访问
/configInfo
,会发现data
字段已更新 —— 证明动态刷新生效!
3. Nacos 分类配置:3 种方案区分环境(命名空间 / Group/DataId)
当项目有多个环境(dev/test/prod)或多个服务时,需要用 Nacos 的 “三维度”(Namespace/Group/DataId)实现配置隔离。我们详细拆解 3 种常用方案:
3.1 方案 1:DataId 方案(最常用,按环境区分 DataId)
核心逻辑:
前提:同一 Namespace(默认 public)、同一 Group(默认 DEFAULT_GROUP);
隔离方式:不同环境用不同 DataId,通过
spring.profiles.active
切换。
实操步骤:
在 Nacos 创建 2 个配置(dev/test 环境):
DataId1:
config-center-dev.yaml
(dev 环境,内容:config.info: "dev环境配置"
);DataId2:
config-center-test.yaml
(test 环境,内容:config.info: "test环境配置"
);
修改bootstrap.yml的spring.profiles.active:
切换到 dev:
active: dev
→拉取config-center-dev.yaml
;切换到 test:
active: test
→拉取config-center-test.yaml
;
测试:启动项目,访问
/configInfo
,会看到对应环境的配置。
适用场景:
单团队、少环境(如 dev/test/prod),配置隔离简单直观。
3.2 方案 2:Group 方案(按服务分组,同一环境不同服务)
核心逻辑:
前提:同一 Namespace(默认 public)、同一 DataId;
隔离方式:不同服务 / 模块用不同 Group,通过
spring.cloud.nacos.config.group
指定。
实操步骤:
在 Nacos 创建 2 个配置(同一 DataId,不同 Group):
DataId:
config-center-info.yaml
(统一 DataId);Group1:
DEV_GROUP
(dev 环境服务 A,内容:config.info: "DEV_GROUP配置"
);Group2:
TEST_GROUP
(test 环境服务 B,内容:config.info: "TEST_GROUP配置"
);
修改bootstrap.yml,指定 Group:
spring:cloud:nacos:config:group: DEV_GROUP # 拉取DEV_GROUP的config-center-info.yaml
测试:启动项目,会拉取对应 Group 的配置。
适用场景:
多服务共用同一配置模板(如数据库连接模板),按服务分组隔离。
3.3 方案 3:Namespace 方案(完全隔离,多环境 / 多团队)
核心逻辑:
前提:不同 Namespace(物理隔离),DataId 和 Group 可重复;
隔离方式:每个环境 / 团队对应一个 Namespace,通过
spring.cloud.nacos.config.namespace
指定(注意:是 Namespace 的ID,不是名称!)。
实操步骤:
在 Nacos 创建 2 个 Namespace:
新建 Namespace1:名称
dev
,ID 自动生成(如760ae4af-1a85-41c7-9db2-44dd58f3f95e
);新建 Namespace2:名称
test
,ID 自动生成(如8d6ba322-4271-430a-9844-31ec3ba614ba
);
在对应 Namespace 下创建配置:
在
dev
Namespace 下创建config-center-dev.yaml
(内容:config.info: "dev Namespace配置"
);在
test
Namespace 下创建config-center-test.yaml
(内容:config.info: "test Namespace配置"
);
修改bootstrap.yml,指定 Namespace 的 ID:
spring:cloud:nacos:config:namespace: 760ae4af-1a85-41c7-9db2-44dd58f3f95e # dev的Namespace ID
测试:启动项目,会拉取指定 Namespace 下的配置。
我们的易错点提醒:
Namespace 用 ID 不用名称:Nacos 控制台显示 “名称”,但配置时需要填 “ID”(创建时自动生成,可在 Namespace 列表查看),填名称会导致配置拉取失败!
4. 进阶:Nacos 配置中心整合 MyBatis(2 种连接池方式)
我们在ConfigCenter
项目中整合 MyBatis,重点实现 “数据源配置从 Nacos 拉取”,提供两种连接池方案:德鲁伊(Druid)连接池(常用,带监控)和自定义 Hikari 连接池(默认,轻量)。
4.1 通用准备:在 Nacos 创建数据源配置
首先在 Nacos 创建数据源配置文件,DataId 遵循规则:config-center-datasource.yaml
(prefix=config-center,active=datasource,file-extension=yaml)。
Nacos 配置内容(DataId:config-center-datasource.yaml):
# 服务端口(从Nacos拉取,覆盖本地配置)server:port: 8081# 数据源配置(MyBatis需要)spring:datasource:# 1. 通用配置(两种连接池都需要)url: jdbc:mysql://localhost:3306/user_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=trueusername: rootpassword: ${DB_PASSWORD:root} # 支持占位符:优先取环境变量DB_PASSWORD,没有则用默认值rootdriver-class-name: com.mysql.cj.jdbc.Driver# 2. 德鲁伊连接池专用配置(方案1用,方案2注释)druid:initial-size: 5 # 初始化连接数min-idle: 5 # 最小空闲连接数max-active: 20 # 最大活跃连接数max-wait: 60000 # 获取连接的最大等待时间(毫秒)time-between-eviction-runs-millis: 60000 # 检测间隔时间(毫秒)min-evictable-idle-time-millis: 300000 # 连接最小空闲时间(毫秒)validation-query: SELECT 1 FROM DUAL # 验证SQLtest-while-idle: true # 空闲时检测test-on-borrow: false # 借用时检测test-on-return: false # 返回时检测pool-prepared-statements: true # 开启预编译max-pool-prepared-statement-per-connection-size: 20 # 预编译语句池大小filters: stat,wall,log4j2 # 启用监控、防SQL注入、日志(需加对应依赖)connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 慢SQL阈值(5秒)# 3. Hikari连接池专用配置(方案2用,方案1注释)# hikari:# maximum-pool-size: 20 # 最大连接数# minimum-idle: 5 # 最小空闲连接数# idle-timeout: 300000 # 空闲超时时间(毫秒)# connection-timeout: 20000 # 连接超时时间(毫秒)# pool-name: MyHikariCP # 连接池名称
4.2 方案 1:整合德鲁伊(Druid)连接池(推荐,带监控)
步骤 1:加德鲁伊与 MyBatis 依赖
在ConfigCenter
的pom.xml
中添加:
<!-- 1. 德鲁伊连接池依赖(带Spring Boot支持) --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.16</version></dependency><!-- 2. MySQL驱动(适配MySQL 8.x) --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.32</version><scope>runtime</scope></dependency><!-- 3. MyBatis Spring Boot Starter --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version></dependency><!-- 4. 德鲁伊监控日志依赖(可选,配合filters: log4j2) --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.20.0</version></dependency>
步骤 2:配置德鲁伊数据源(绑定 Nacos 配置)
用@ConfigurationProperties
自动绑定 Nacos 中的spring.datasource.druid
配置,无需手动注入参数:
package com.lh.configcenter.config;import com.alibaba.druid.pool.DruidDataSource;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import javax.sql.DataSource;@Configuration@MapperScan("com.zh.configcenter.mapper") // 扫描MyBatis的Mapper接口public class DruidMyBatisConfig {// 1. 配置德鲁伊数据源:自动绑定Nacos中的spring.datasource.druid配置@Bean@ConfigurationProperties(prefix = "spring.datasource.druid") // 前缀对应Nacos配置public DataSource druidDataSource() {// DruidDataSource会自动加载Nacos中的url、username、password等配置return new DruidDataSource();}// 2. 配置SqlSessionFactory(MyBatis核心)@Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource); // 注入德鲁伊数据源// 配置MyBatis核心参数org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();config.setMapUnderscoreToCamelCase(true); // 开启驼峰命名转换(user_name→userName)config.setCacheEnabled(true); // 开启二级缓存sessionFactory.setConfiguration(config);// 配置Mapper XML文件路径(放在resources/mapper目录下)sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));return sessionFactory;}// 3. 配置事务管理器(可选,支持@Transactional)@Beanpublic org.springframework.jdbc.datasource.DataSourceTransactionManager transactionManager(DataSource dataSource) {return new org.springframework.jdbc.datasource.DataSourceTransactionManager(dataSource);}}
4.3 方案 2:自定义 Hikari 连接池(默认,轻量)
Hikari 是 Spring Boot 默认的连接池(轻量、性能好),适合对监控要求不高的场景。
步骤 1:加 Hikari 与 MyBatis 依赖
Hikari 无需额外依赖(Spring Boot 自带),只需加 MySQL 和 MyBatis 依赖(同方案 1 的步骤 1 中的 2、3)。
步骤 2:自定义 Hikari 数据源(手动注入 Nacos 配置)
通过@Value
从 Nacos 拉取数据源参数,手动创建 HikariDataSource:
package com.lh.configcenter.config;import com.zaxxer.hikari.HikariDataSource;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.annotation.MapperScan;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import javax.sql.DataSource;@Configuration@MapperScan("com.zh.configcenter.mapper") // 扫描Mapper接口public class HikariMyBatisConfig {// 从Nacos配置中注入数据源参数@Value("${spring.datasource.url}")private String url;@Value("${spring.datasource.username}")private String username;@Value("${spring.datasource.password}")private String password;@Value("${spring.datasource.driver-class-name}")private String driverClassName;// Hikari专用参数(从Nacos拉取,可选)@Value("${spring.datasource.hikari.maximum-pool-size:20}")private int maxPoolSize;@Value("${spring.datasource.hikari.minimum-idle:5}")private int minIdle;// 1. 自定义Hikari数据源@Beanpublic DataSource hikariDataSource() {HikariDataSource dataSource = new HikariDataSource();// 手动设置从Nacos拉取的参数dataSource.setJdbcUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setDriverClassName(driverClassName);// 设置Hikari连接池参数dataSource.setMaximumPoolSize(maxPoolSize);dataSource.setMinimumIdle(minIdle);dataSource.setPoolName("MyHikariCP"); // 连接池名称return dataSource;}// 2. 配置SqlSessionFactory(和方案1一致)@Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();config.setMapUnderscoreToCamelCase(true);config.setCacheEnabled(true);sessionFactory.setConfiguration(config);sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));return sessionFactory;}}
4.4 步骤 3:修改 bootstrap.yml,拉取数据源配置
spring:application:name: config-centerprofiles:active: datasource # 对应Nacos的DataId:config-center-datasource.yamlcloud:nacos:discovery:server-addr: 127.0.0.1:8848config:server-addr: 127.0.0.1:8848file-extension: yaml# 若用Namespace/Group,需添加对应配置# group: DEFAULT_GROUP# namespace: 760ae4af-1a85-41c7-9db2-44dd58f3f95e
4.5 测试 MyBatis 整合
编写 Mapper 接口(如
UserMapper.java
)和 XML(UserMapper.xml
);编写 Service 和 Controller 调用 Mapper;
启动项目,访问接口,若能正常查询数据库,证明整合成功。
5. 实用技巧:yml 多文档配置(用 --- 分隔)
在实际开发中,我们可以在一个bootstrap.yml
中用---
分隔多个环境的配置,避免创建多个 yml 文件。示例如下:
# ==================== 公共配置 ====================spring:application:name: config-centercloud:nacos:discovery:server-addr: 127.0.0.1:8848config:server-addr: 127.0.0.1:8848file-extension: yaml# ==================== dev环境配置 ====================---spring:profiles: dev # 环境标识:devcloud:nacos:config:group: DEFAULT_GROUP# namespace: 760ae4af-1a85-41c7-9db2-44dd58f3f95e# ==================== test环境配置 ====================---spring:profiles: test # 环境标识:testcloud:nacos:config:group: TEST_GROUP# namespace: 8d6ba322-4271-430a-9844-31ec3ba614ba# ==================== datasource环境配置 ====================---spring:profiles: datasource # 环境标识:datasourcecloud:nacos:config:group: DEFAULT_GROUP# namespace: 760ae4af-1a85-41c7-9db2-44dd58f3f95e
使用方式:启动时通过-Dspring.profiles.active=dev
指定环境,例如:
java -jar ConfigCenter-1.0-SNAPSHOT.jar -Dspring.profiles.active=datasource
6. 重点 & 易错点总结(避坑指南)
重点 / 易错点 | 我们的解决方案 |
---|---|
bootstrap 依赖缺失 | 新版本 Spring Cloud 必须手动引入spring-cloud-starter-bootstrap ,否则无法拉取 Nacos 配置 |
DataId 命名错误 | 严格遵循${prefix}-${active}.${extension} 规则,确保与 bootstrap.yml 的配置完全一致 |
Namespace 用名称不用 ID | Nacos 配置中namespace 需填 “ID”(控制台可查),填名称会导致配置拉取失败 |
动态刷新不生效 | 必须在 Controller 上加@RefreshScope 注解,且@Value 取值的配置项在 Nacos 中存在 |
德鲁伊监控不生效 | 确保 Nacos 中配置了spring.datasource.druid.filters=stat ,且加了 log4j2 依赖 |
MyBatis Mapper 扫描不到 | 在配置类上加@MapperScan("com.zh.configcenter.mapper") ,指定 Mapper 接口路径 |
7. 总结
Nacos 配置中心是微服务架构的 “配置大脑”,核心价值在于 “统一管理、环境隔离、实时更新”。我们需要重点掌握:
yml 与 Nacos 的对应关系:DataId 的命名规则是核心,错一个字符都会导致配置拉取失败;
分类配置方案:根据团队规模和环境数量选择 DataId/Group/Namespace 方案;
MyBatis 整合:两种连接池方式按需选择,德鲁伊适合需要监控的场景,Hikari 适合轻量场景;
多文档配置:用
---
分隔环境,简化配置文件管理。
后续学习中,我们可以进一步探索 Nacos 的 “配置加密”(敏感配置如密码加密存储)、“灰度发布”(配置仅推送给部分服务)等高级功能,让配置管理更安全、灵活。