Nacos Service Registry

📢 This article was translated by gemini-3-flash-preview

Install the software first. Official website: https://nacos.io/en/

You can change the port in the conf/application.properties file; the default is 8848.

Service Registration

Add the management dependency in the parent project:

1
2
3
4
5
6
7
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.6.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

Comment out the Eureka dependency and add the Nacos client dependency:

1
2
3
4
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

Modify application.yml to add the Nacos address and comment out the Eureka address:

1
2
3
4
spring:
  cloud:
    nacos:
      server-addr: localhost:8848

Start Nacos:

1
2
startup.cmd -m standalone
# The parameter is for standalone mode

Access http://localhost:8848/nacos/ . The default username and password are both nacos.

Tiered Storage Model

Services are divided into multiple clusters, each containing multiple instances. Clusters can be assigned by region to improve access speed.

In contrast, Eureka only has a Service-Instance model without clusters.

Service calls should prioritize the local cluster to avoid high latency. If the local cluster is unavailable, Nacos will fail over to other clusters.

You can set the cluster in application.yml:

1
2
3
4
5
6
spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: Shanghai # Cluster name

Then set the Ribbon strategy to Nacos’s strategy:

1
2
3
4
5
# Configure load balancing rules for a specific microservice, here it's userService
userService:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
#    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.Nac # Load balancing rule

You can also set the instance weight (0-1) in the Nacos console. Higher weight means higher access frequency.

Environment Isolation

The outermost layer for service and data storage in Nacos is the namespace, which is used for top-level isolation.

You can create a new namespace in Nacos, such as dev, and then update application.yml:

1
2
3
4
5
6
7
spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: Shanghai # Cluster name
        namespace: UUID # The UUID of the namespace

Services in different namespaces are invisible to each other and cannot be accessed.

Ephemeral vs. Non-ephemeral Instances

For ephemeral instances, Nacos handles them the same way as Eureka (heartbeats).

For non-ephemeral instances, Nacos actively probes the service for health. The service is not deleted if it becomes unavailable, and Nacos will actively notify consumers about the failure.

Set an instance as non-ephemeral:

1
2
3
4
5
spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false # Set as non-ephemeral

Nacos Configuration Management

As the number of microservice instances grows, changing configurations one by one becomes tedious. Nacos allows for centralized configuration management with hot updates.

Basic Usage

In the Nacos console’s Configuration Management, create a new configuration. The Data ID is the config file ID, formatted as [service-name]-[profile].[extension], e.g., userService-dev.yaml.

Then write the configuration content:

1
2
pattern: 
  dateformat: yyyy-MM-dd HH:mm:ss

Add the Nacos configuration management client dependency:

1
2
3
4
5
<!--nacos configuration management dependency-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

Configuration retrieval steps:

App Start -> bootstrap.yml -> Nacos config file -> Local application.yml -> Create Spring Container -> Load beans

Add bootstrap.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
spring:
  application:
    name: userService # Service name
  profiles:
    active: dev # Active profile
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos address
      config:
        file-extension: yaml # File extension

Testing:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@RestController
@RequestMapping("/user")
public class UserController{
    
    @Value("${pattern.dateformat}")
    private String dateformat;
    
    @GetMapping("/now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }
}

Check the page to see the effect.

Hot Updates

This can be achieved in two ways:

Method 1: Add the @RefreshScope annotation to the class where the @Value is injected.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@RefreshScope // Enable automatic configuration refresh
@RestController
@RequestMapping("/user")
public class UserController{
    
    @Value("${pattern.dateformat}")
    private String dateformat;
    
    @GetMapping("/now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }
}

Method 2: Use @ConfigurationProperties.

Create a configuration class:

1
2
3
4
5
6
@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
    private String dateformat;
}

Controller class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// @RefreshScope // Not needed with @ConfigurationProperties
@RestController
@RequestMapping("/user")
public class UserController{
    
    @Autowired
    private PatternProperties properties;
    
    @GetMapping("/now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDateformat()));
    }
}

Shared Configuration

When a microservice starts, it reads multiple configuration files from Nacos:

  • [spring.application.name]-[spring.profiles.active].yaml, e.g., userService-dev.yaml
  • [spring.application.name].yaml, e.g., userService.yaml

The second one ([spring.application.name].yaml) does not include the environment profile and can be shared across multiple environments.

Configuration priority: [spring.application.name]-[spring.profiles.active].yaml > [spring.application.name].yaml > Local configuration.

This post is licensed under CC BY-NC-SA 4.0 by the author.
Last updated on 2025-02-05 17:37 +0900