When developing microservices with SpringCloud, you often encounter relatively small backend parameter configurations that are not large enough to be stored in a separate table and that are read by other services. For example, IP whitelisting. In this case, it is easier to use Nacos to save and read them.

Configuration

Adding dependencies

1
2
3
4
5
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>${latest.version}</version>
</dependency>
  • Nacos version 2.1.xRELEASE corresponds to Spring Boot version 2.1.x.
  • Nacos version 2.0.xRELEASE corresponds to Spring Boot version 2.0.x.
  • Nacos version 1.5.xRELEASE corresponds to Spring Boot version 1.5.x.

Nacos Release Notes Wiki

Nacos server configuration

Configure the address and application name of the Nacos server in the microservice configuration.

1
2
3
4
5
6
7
8
spring:
  application:
    name: service-xxx
  cloud:
    nacos:
      config:
        server-addr: ${spring.cloud.nacos.discovery.server-addr}
        file-extension: yaml

The reason you need to configure spring.application.name is because it is part of the dataId field that makes up the Nacos configuration management.

In Nacos Spring Cloud, the full format of dataId is as follows.

1
${prefix}-${spring.profiles.active}.${file-extension}
  • prefix defaults to the value of spring.application.name, and can also be configured via the configuration item spring.cloud.nacos.config.prefix.

  • spring.profiles.active is the corresponding profile for the current environment, you can refer to the Spring Boot documentationfor details.

    Note: When spring.profiles.active is empty, the corresponding linker - will also not exist, and the splicing format of dataId will become ${prefix}. ${file-extension}

  • file-exetension is the data format of the configuration content, which can be configured via the configuration item spring.cloud.nacos.config.file-extension. Currently only properties and yaml types are supported.

Injecting configuration

Once you have configured Nacos as a configuration center as above, you can turn on automatic fetching of values from Nacos by adding SpringCloud native annotations to the configuration class, for example

  • @Value direct injection of variable values
  • @ConfigurationProperties consolidates several variables into a single Properties class

To enable automatic synchronization of changes to Nacos variables, add the @RefreshScope annotation to the class into which the variables are injected.

Nacos also provides its own annotations specific to it.

Spring Cloud Annotations Nacos Spring Annotations Remarks
@Value @NacosValue auto-refreshed
@ConfigurationProperties @NacosConfigurationProperties auto-refreshed, @NacosProperty set for a property, @NacosIgnore Nacos ignores the value

Generally, the variables we inject are configured in the configuration file of the microservice, e.g. application.yaml. But sometimes, we want to save some configuration as a separate nacos configuration, i.e., with a separate dataId, and then we need to use extension-configigs.

For example, there is the following configuration.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@Component
@RefreshScope
@ConfigurationProperties(prefix = "test")
public class TestProperties {
    private List<String> whiteList;

    public List<String> getWhiteList() {
        return whiteList;
    }

    public void setWhiteList(List<String> whiteList) {
        this.whiteList = whiteList;
    }

}

We want to create a test.properties configuration on nacos to store the values of the properties, so we need to modify the microservice configuration file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
spring:
  application:
    name: service-xxx
  cloud:
    nacos:
      config:
        server-addr: ${spring.cloud.nacos.discovery.server-addr}
        file-extension: yaml
        extension-configs[0]:
          data-id: test.properties
          refresh: true

extension-configs[n] can be added multiple times, each containing three configurations.

  • data-id The standalone data-id, which must end with properties or yaml and is not affected by spring.cloud.nacos.config.file-extension
  • group The configuration of a separate group.
  • refresh whether to enable auto-refresh, default false

In this way, the nacos configuration of independent profiles and the automatic update of their values are implemented.

Synchronous configuration

On top of the above, let’s add another feature: microservice modifies variable values from local and uploads them to nacos, other instances of the same microservice, get the same value when fetching, then we need to call nacos’ native API NacosConfigManager.

1
2
3
4
//Push local configuration to Nacos
configManager.getConfigService().publishConfig("test.properties", "DEFAULT_GROUP", contentToString(ConfigType.PROPERTIES));
//Pulling configuration from Nacos
configManager.getConfigService().getConfig("test.properties", "DEFAULT_GROUP", 100l)

Note

  1. Suppose there are two instances of the current microservice: A and B. We update the value of TestProperties to Nacos by publishConfig on A. Then the other instance, B, will receive a notification from Nacos to get the latest value from nacos, but there will be a millisecond delay in between.
  2. Nacos also provides APIs such as @NacosInject, ConfigService, etc., but these APIs can only be used in SpringBoot and cannot be used directly in SpringCloud.

Reference: http://edisonxu.com/2022/07/08/spring-cloud-nacos-variable.html