Recently Nacos has been used as the configuration center and registry, and there have been some problems in the process of using it. Some are framework issues, some are usage issues. I also shared a recent article “Some problems with using Nacos” not long ago, if you are interested, you can check it out.

Today’s topic is also found in the process of using, mainly because I was too busy to catch up with the schedule in the early stage, so I had time to tidy up and think about a better way after stopping.

Environmental isolation

Environmental isolation is one of the most basic requirements. In the daily development process, different environments are often required, such as development, testing, pre-release, and online environments.

In Nacos there is the concept of namespaces to support multi-environment isolation by space, i.e. one namespace for each environment

We can create multiple Spaces for isolation as shown below:

If you need physical isolation, you need to deploy multiple Nacos environments, which we currently do. The main reason for deploying multiple environments is that currently there is no complete permission control, and it is very dangerous to expose the configuration of the production environment to everyone directly. It is said that the next release will add permission related functions.

Tenant isolation is another application scenario. From the perspective of multiple tenants (users), each tenant (user) may have its own namespace, and the configuration data and registered service data of each tenant (user) belong to its own namespace to achieve data isolation among tenants. For example, the super administrator assigns three tenants, namely, Zhang SAN, Li Si, and Wang Wu. After the namespace is assigned, each tenant logs in with his/her own account name and password to create his/her own namespace. As shown below:

But this feature is in the works and will be supported later. We are also moving towards this in terms of usage. Different environments are currently separated by multiple deployments, so namespace has to be valued and meaningful elsewhere.

Namespaces can be divided according to internal product lines, and configuration files can be subdivided under each namespace. One problem is that if multiple product lines have shared configuration information before, that is, shared configuration, only one copy can be stored on each side.

Namespace has been isolated, if you want to configure sharing across namespaces, I wonder if there is any plan to support such a function.

The namespace design of Nacos is designed to distinguish multi-environment or multi-tenant. In this way, cross-namespace is a special requirement, so we need to take into account the need for configuration planning. If there are common configurations that need to be shared, they should be put into the same namespace.

Classification of configuration

Generally, at the beginning of the use, it does not think too much, and directly creates a corresponding application configuration for each project, and puts all the configuration in it. A small amount of configuration is ok, but a large amount of configuration is not recommended. We need specific classification to make the configuration more clear at a glance.

In addition to this problem, there is also some configuration that needs to be shared, which is not independent, and there is a copy of the same configuration in the application of each project. In case you need to modify it one day, you will find that it is not enough to change one place, and many places have to be changed.

Here is how I classified, everyone has their own ideas, and there is no standard, just for reference:

Group

Group is used for grouping. DEFAULT_GROUP is used by default. I have three groups as follows:

  1. MIDDLEWARE_GROUP

Middleware configuration, such as Redis, Mq, etc.

  1. APPLICATION_GROUP

Application configuration, such as Jackson, SpringBoot Actuator, etc.

  1. BIZ_GROUP

Business configuration, business related, such as order timeout, unpaid time, global postage, etc.

DataId

DataId is the ID, or unique identifier, of the configuration.

Usually named after the service name, as shown below:

  1. xxx-order-biz (BIZ_GROUP)
  2. xxx-order-application (APPLICATION_GROUP)

The middleware configuration is named after the middleware name as follows:

  1. xxx-redis (MIDDLEWARE_GROUP)
  2. xxx-rocketmq (MIDDLEWARE_GROUP)
  3. xxx-elasticsearch (MIDDLEWARE_GROUP)

With a detailed classification, we can import the DataId that we need, not all of it, and not modify every configuration file. We can use the following:

@NacosPropertySource(dataId = NacosConstant.REDIS, groupId = NacosConstant.MIDDLEWARE_GROUP, autoRefreshed = true)
@NacosPropertySource(dataId = NacosConstant.ORDER_BIZ, groupId = NacosConstant.BIZ_GROUP, autoRefreshed = true)
@NacosPropertySource(dataId = NacosConstant.ORDER_APPLICATION, groupId = NacosConstant.APPLICATION_GROUP, autoRefreshed = true)
Copy the code

Configured to use

The most common way to read the checksum field is through the @nacosValue annotation, and awkwardly, I often forget to set the autochecksum field in @nacosValue to true, and find that the configuration changes don’t take effect in real time and have to be refreshed.

I suggest or don’t use @ around NacosValue annotations to read configuration, configuration can be unified management, such as using the @ NacosConfigurationProperties is very convenient.

@Data
@Configuration
@NacosConfigurationProperties(dataId = NacosConstant.ORDER_BIZ, groupId = NacosConstant.BIZ_GROUP, autoRefreshed = true) public class OrderBizConfig {/** ** postage */ private BigDecimal postage; }Copy the code

As business configuration also has many types, each type can be used a @ NacosConfigurationProperties, calculate don’t @ NacosConfigurationProperties can also create a separate configuration class, By using @nacosValue in this class, the user can inject the configuration class directly in case the configuration key needs to be changed or removed.

@data@configuration public class OrderBizConfig {/** * postage */ @nacosValue (value ="${postage}", autoRefreshed = true)
    private BigDecimal postage;
}
Copy the code