Spring Cloud Microservices Tutorial – Revised Part 5: Using Nacos Config Center
This article shows how to replace scattered application.yml files with a centralized Nacos configuration center, enabling real‑time configuration updates, environment isolation, version control, and dynamic refresh without restarting Spring Cloud services.
Goal
Unify configuration management for multiple Spring Cloud services by using Nacos as a centralized configuration center.
Problems without a configuration center
Configuration files are scattered across services (each service has its own application.yml).
Changing a property requires editing many files and rebuilding each service.
Configuration changes trigger service restarts and redeployments.
Development, test and production settings are mixed.
No version control for configuration changes.
Benefits of Nacos Config Center
All configurations are stored in one place.
Changes take effect in real time without restarting services.
Environment isolation via namespace and group.
Version history and one‑click rollback.
Project structure (new files)
spring-cloud-teaching-ep05/
├── pom.xml # add Nacos config dependency
├── docker-compose.yml
├── user-service/
│ ├── pom.xml
│ └── src/main/resources/
│ ├── bootstrap.yml # higher priority than application.yml
│ └── application.yml
├── order-service/
│ ├── pom.xml
│ └── src/main/resources/
│ ├── bootstrap.yml
│ └── application.yml
├── gateway/
│ ├── pom.xml
│ └── src/main/resources/
│ ├── bootstrap.yml
│ └── application.yml
└── README.mdPrepare Nacos configurations
Open http://localhost:8848/nacos → Configuration Management → Add new configurations.
User Service configuration (YAML)
# user-service-dev.yml
user:
config:
name: "教学用户服务"
version: "1.0.0"
enable-cache: true
page-size: 10Order Service configuration (YAML)
# order-service-dev.yml
order:
config:
name: "教学订单服务"
version: "1.0.0"
max-batch-size: 100
enable-feign-log: trueCommon Redis configuration (optional)
# common-redis.yml
spring:
redis:
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD:}Add Nacos config dependency
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>Service refactoring
User Service
bootstrap.yml (higher priority)
spring:
application:
name: user-service
profiles:
active: dev
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yaml
group: TEACHING_GROUP
refresh-enabled: true
discovery:
server-addr: localhost:8848application.yml (static part)
server:
port: 8081
logging:
level:
com.teaching: DEBUGConfigController (dynamic refresh)
package com.teaching.user.controller;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/config")
@RefreshScope
public class ConfigController {
@Value("${user.config.name:默认名称}")
private String serviceName;
@Value("${user.config.version:1.0}")
private String version;
@Value("${user.config.enable-cache:false}")
private Boolean enableCache;
@Value("${user.config.page-size:10}")
private Integer pageSize;
@GetMapping("/info")
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>();
config.put("serviceName", serviceName);
config.put("version", version);
config.put("enableCache", enableCache);
config.put("pageSize", pageSize);
return config;
}
}Order Service (similar changes)
# bootstrap.yml
spring:
application:
name: order-service
profiles:
active: dev
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yaml
group: TEACHING_GROUP
refresh-enabled: true
discovery:
server-addr: localhost:8848
# application.yml
server:
port: 8082
logging:
level:
com.teaching: DEBUG package com.teaching.order.controller;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/config")
@RefreshScope
public class ConfigController {
@Value("${order.config.name:默认名称}")
private String serviceName;
@Value("${order.config.version:1.0}")
private String version;
@Value("${order.config.max-batch-size:50}")
private Integer maxBatchSize;
@Value("${order.config.enable-feign-log:false}")
private Boolean enableFeignLog;
@GetMapping("/info")
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>();
config.put("serviceName", serviceName);
config.put("version", version);
config.put("maxBatchSize", maxBatchSize);
config.put("enableFeignLog", enableFeignLog);
return config;
}
}Validate dynamic refresh
Start Nacos: docker-compose up -d Create the configurations described above in Nacos.
Run the services:
cd user-service
mvn spring-boot:run
cd ../order-service
mvn spring-boot:runQuery the configuration:
curl http://localhost:8081/api/config/infoExpected JSON shows values from Nacos.
Modify user.config.page-size from 10 to 20 in Nacos, then call the endpoint again – the response shows pageSize: 20 without restarting.
Multi‑environment configuration
Define separate Data IDs for each environment, e.g. user-service-dev.yml, user-service-test.yml, user-service-prod.yml. Switch environments by changing spring.profiles.active in bootstrap.yml or via JVM arguments:
java -jar user-service.jar --spring.profiles.active=prodConfiguration priority
High → Low:
1. JVM arguments (-Dkey=value)
2. Environment variables (${ENV_VAR})
3. Nacos Config Center
4. bootstrap.yml
5. application.ymlShared configuration
Create a common configuration file (e.g., common-redis.yml) in Nacos and import it with shared-configs in bootstrap.yml:
spring:
cloud:
nacos:
config:
shared-configs:
- data-id: common-redis.yml
group: TEACHING_GROUP
refresh: trueCommon issues & solutions
Issue 1: Config not taking effect
Ensure the controller class is annotated with @RefreshScope.
Verify the Data ID follows the pattern
${spring.application.name}-${spring.profiles.active}.${file-extension}.
Confirm refresh-enabled: true is set in bootstrap.yml.
Issue 2: bootstrap.yml not loaded
Spring Boot 2.4+ disables bootstrap by default. Add the dependency spring-cloud-starter-bootstrap to restore the behavior:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>Issue 3: Confusing configuration priority
Separate responsibilities: bootstrap.yml holds Nacos address, application name, and active profile. application.yml contains static settings such as server port and logging.
Nacos stores business‑specific and dynamic properties.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Coder Trainee
Experienced in Java and Python, we share and learn together. For submissions or collaborations, DM us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
