Building Microservices with Nacos: Registration, Discovery, Load Balancing & Config
This tutorial walks through setting up Nacos as a cloud‑native service registry and configuration center, covering installation modes, service registration, discovery, load‑balancing with Spring Cloud, dynamic configuration loading, namespace isolation, and best‑practice patterns for managing microservice environments.
1. Install Nacos (standalone mode)
Download a stable release (e.g., 2.5.1) from the official Nacos download page and unzip the package.
sh startup.sh -m standaloneIf you are on Windows, run startup.cmd -m standalone instead.
Successful startup logs contain lines similar to:
2025-06-14 09:02:57,731 INFO Tomcat started on port(s): 8848 (http) with context path '/nacos'
2025-06-14 09:02:57,749 INFO Nacos started successfully in stand alone mode. use embedded storageOpen http://127.0.0.1:8848/nacos to view the Nacos console.
2. Service Registration
When a Spring Cloud microservice starts, it registers itself to Nacos. The default registration uses:
Namespace: public Group: DEFAULT_GROUP Example registration log:
2025-06-14 09:02:57,748 INFO Started Nacos in 4.437 seconds (JVM running for 4.716)3. Service Discovery & Load Balancing
3.1 Enable discovery
@EnableDiscoveryClient
@SpringBootApplication
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class);
}
}Alternatively, use @NacosServiceDiscovery provided by Nacos.
3.2 Remote call (fixed instance)
private Product getProductRemote(Long productId) {
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
ServiceInstance instance = instances.get(0);
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/product/" + productId;
System.out.println("Remote call: " + url);
return restTemplate.getForObject(url, Product.class);
}This selects the first instance and therefore does not provide load balancing.
3.3 Load‑balanced call (Spring Cloud LoadBalancer)
Add the dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>Inject LoadBalancerClient and choose an instance:
private Product getProductRemoteLoadBalance(Long productId) {
ServiceInstance instance = loadBalancerClient.choose("service-product");
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/product/" + productId;
System.out.println("Remote call: " + url);
return restTemplate.getForObject(url, Product.class);
}Or use the annotation‑based approach:
@Configuration
public class OrderServiceConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}With @LoadBalanced, the URL can be written as http://service-product/product/{id} and the client will automatically resolve the instance via round‑robin.
In production, the annotation‑based approach is preferred because it hides the load‑balancer client logic.
4. Configuration Center
4.1 Add Nacos Config dependency
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>If a service does not need a Nacos data set, disable the import‑check:
spring.cloud.nacos.config.import-check.enabled=false4.2 Import configuration data sets
In each service’s application.properties (or application.yml) add:
spring.config.import=nacos:service-order.propertiesand for the product service:
spring.config.import=nacos:service-product.properties4.3 Create data sets in the Nacos console
Navigate to **Configuration Management → Configuration List → Create Configuration**, select the appropriate namespace and group (e.g., DEFAULT_GROUP), and add key‑value pairs such as:
order.timeout=30s
order.auto-confirm=7d4.4 Read configuration in code
@RestController
public class OrderController {
@Value("${order.timeout}")
private String orderTimeout;
@Value("${order.auto-confirm}")
private String orderAutoConfirm;
@GetMapping("/order/config")
public String getConfig() {
return "orderTimeout=" + orderTimeout + ", orderAutoConfirm=" + orderAutoConfirm;
}
}Alternatively, bind a group of properties with @ConfigurationProperties:
@Component
@ConfigurationProperties(prefix = "order")
@Data
public class OrderProperties {
private String timeout;
private String autoConfirm;
}Inject OrderProperties wherever needed.
4.5 Dynamic refresh
Three ways to refresh configuration at runtime: @RefreshScope together with @Value – bean is recreated on change. @ConfigurationProperties – properties are automatically refreshed.
Programmatic listener via NacosConfigManager:
@SpringBootApplication
public class OrderApplication {
@Bean
ApplicationRunner runner(NacosConfigManager manager) {
return args -> {
ConfigService cs = manager.getConfigService();
cs.addListener("service-order.properties", "DEFAULT_GROUP", new Listener() {
@Override public Executor getExecutor() { return Executors.newFixedThreadPool(4); }
@Override public void receiveConfigInfo(String config) {
System.out.println("New config: " + config);
// e.g., send email, reload cache
}
});
System.out.println("Application started");
};
}
}4.6 Environment isolation with namespaces and groups
Create separate namespaces in Nacos for each environment (e.g., dev, test, prod). In the Spring Boot configuration specify the namespace dynamically:
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
config:
namespace: ${spring.profiles.active:dev}Group the configuration files by service name (e.g., service-order) and import them with the ?group=service-order suffix. Use multi‑profile application.yml to load environment‑specific data sets:
spring:
config:
import:
- nacos:common.properties?group=service-order
- nacos:database.properties?group=service-order
---
spring:
config:
import:
- nacos:common.properties?group=service-order
- nacos:database.properties?group=service-order
- nacos:local.properties?group=service-order
activate:
on-profile: test
---
spring:
config:
import:
- nacos:common.properties?group=service-order
- nacos:database.properties?group=service-order
- nacos:third-party.properties?group=service-order
activate:
on-profile: prodThe first block is used for the dev profile, the second for test, and the third for prod. Nacos will load the appropriate data sets based on the active Spring profile.
Configuration priority: Nacos data sets override local application.properties . When multiple data sets are imported, the earlier ones have higher precedence.
5. Summary
This guide demonstrates how to use Nacos as both a service registry and a configuration center. It covers installation, service registration, discovery, three load‑balancing strategies, reading and dynamically refreshing configuration, and isolating environments with namespaces and groups. Subsequent articles will explore Nacos clustering and advanced production practices.
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.
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.
