Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Service Discovery and Configuration Management with Nacos

Tech 1

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

  1. Download the appropriate package from the official site and extract it.
  2. For Windows, modify config/application.properties to set a secret key (e.g., nacos.core.auth.plugin.nacos.token.secret.key with a value over 32 characters). Adjust bin/startup.cmd to include set MODE="standalone". On Linux, start with -m standalone.
  3. Access the web interface at http://localhost:8848 after 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.

  1. Edit conf/cluster.conf to list all node IPs and ports (e.g., 192.168.1.10:8848).
  2. Configure an external database by initializing MySQL with the provided SQL script and updating application.properties to point to it.
  3. 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

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.