Implementing Service Discovery and Configuration Management with Nacos
Nacos is a platform designed for dynamic service discovery, configuration management, and service orchestration in cloud-native applications. It combines the functionalities of a service registry and a configuration center, similar to integrating Eureka, Config, and Bus.
Core Capabilities
- Service Registration: Clients register with the server via REST requests, providing metadata such as IP addresss and port. The server stores this information in a two-tiered in-memory map.
- Service Heartbeat: After registration, clients send periodic heartbeats (default every 5 seconds) to indicate availability and prevent removal.
- Service Synchronization: Server clusters synchronize service instances to ensure consistency.
- Service Discovery: Consumers retrieve service lists from the server through REST requests, caching them locally and periodically updating the cache.
- Health Monitoring: The server runs scheduled tasks to check instance health. Instances without a heartbeat for 15 seconds are marked unhealthy, and those exceeding 30 seconds are removed, with re-registration possible upon recovery.
Setting Up Nacos in Standalone Mode
Installation and Startup
- Download the appropriate package from the official site and extract it.
- For Windows, modify
config/application.propertiesto set a secret key (e.g.,nacos.core.auth.plugin.nacos.token.secret.keywith a value over 32 characters). Adjustbin/startup.cmdto includeset MODE="standalone". On Linux, start with-m standalone. - Access the web interface at
http://localhost:8848after startup.
Integrating with Spring Boot
Add the following dependencies in your pom.xml:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
Configure application.yml:
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
Annotate the main class with @EnableDiscoveryClient. Upon startup, check logs for registration confirmation, such as nacos registry, DEFAULT_GROUP user-service 192.168.1.100:8080 register finished.
Service Isolation Mechanisms
Namespace Isolation
Namespaces anable environment segregation, such as separating development from production. Create a namespace via the web UI and reference it in configuration:
spring:
cloud:
nacos:
discovery:
namespace: namespace-id-here
Grouping Services
Group related services using spring.cloud.nacos.discovery.group. For example, group payment-related services under a common identifier.
Cluster Configuration
Set spring.cloud.nacos.discovery.cluster-name to define a cluster. Instances within the same cluster are prioritized for local calls. The NacosRule class demonstrates this by filtering instances based on cluster name before applying load balancing.
public class CustomRule extends AbstractLoadBalancerRule {
@Override
public Server choose(Object key) {
String targetCluster = this.discoveryProps.getClusterName();
DynamicServerListLoadBalancer balancer = (DynamicServerListLoadBalancer) getLoadBalancer();
String serviceName = balancer.getName();
NamingService namingClient = discoveryProps.namingServiceInstance();
List<Instance> allInstances = namingClient.selectInstances(serviceName, true);
if (StringUtils.hasText(targetCluster)) {
List<Instance> clusterInstances = allInstances.stream()
.filter(inst -> targetCluster.equals(inst.getClusterName()))
.collect(Collectors.toList());
if (!clusterInstances.isEmpty()) {
allInstances = clusterInstances;
}
}
Instance selected = ExtendBalancer.getHostByRandomWeight2(allInstances);
return new NacosServer(selected);
}
}
Enabling Authentication
Modify application.properties on the server:
nacos.core.auth.enabled=true
nacos.core.auth.server.identity.key=authKey
nacos.core.auth.server.identity.value=authValue
In client configuration, add credentials:
spring:
cloud:
nacos:
discovery:
username: nacos
password: nacos
Deploying a Nacos Cluster
Cluster Setup
Use a domain with a load balancer (e.g., SLB) for high availability. Prepare multiple machines and install Nacos on each.
- Edit
conf/cluster.confto list all node IPs and ports (e.g.,192.168.1.10:8848). - Configure an external database by initializing MySQL with the provided SQL script and updating
application.propertiesto point to it. - Start each node with
bin/startup.sh.
Client configuration for the cluster:
spring:
cloud:
nacos:
discovery:
server-addr: node1:8848,node2:8848,node3:8848
username: nacos
password: nacos
Integrating with Nginx for Load Balancing
Install Nginx with stream module support:
./configure --with-stream
make && make install
Configure Nginx to handle both HTTP and gRPC traffic:
http {
upstream nacos-http {
server 192.168.1.10:8848;
server 192.168.1.11:8848;
server 192.168.1.12:8848;
}
server {
listen 8848;
location / {
proxy_pass http://nacos-http/;
}
}
}
stream {
upstream nacos-grpc {
server 192.168.1.10:9848;
server 192.168.1.11:9848;
server 192.168.1.12:9848;
}
server {
listen 9848;
proxy_pass nacos-grpc;
}
}
Update client configuration to use the Nginx endpoint:
spring:
cloud:
nacos:
discovery:
server-addr: nginx-host:8848