Cloud Native 12 min read

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.

Coder Trainee
Coder Trainee
Coder Trainee
Spring Cloud Microservices Tutorial – Revised Part 5: Using Nacos Config Center

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.md

Prepare 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: 10

Order Service configuration (YAML)

# order-service-dev.yml
order:
  config:
    name: "教学订单服务"
    version: "1.0.0"
    max-batch-size: 100
    enable-feign-log: true

Common 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:8848

application.yml (static part)

server:
  port: 8081
logging:
  level:
    com.teaching: DEBUG

ConfigController (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:run

Query the configuration:

curl http://localhost:8081/api/config/info

Expected 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=prod

Configuration priority

High → Low:
1. JVM arguments (-Dkey=value)
2. Environment variables (${ENV_VAR})
3. Nacos Config Center
4. bootstrap.yml
5. application.yml

Shared 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: true

Common 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MicroservicesNacosYAMLSpring CloudBootstrapDynamic RefreshConfig Center
Coder Trainee
Written by

Coder Trainee

Experienced in Java and Python, we share and learn together. For submissions or collaborations, DM us.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.