Cloud Native 34 min read

Why Nacos Beats Eureka: Hands‑On Guide to Service Discovery, Config Center & Cluster

This article explains Nacos' advantages over Eureka, compares its Raft‑based consistency, details the Spring Cloud Alibaba suite, walks through Nacos architecture, installation, standalone and cluster modes, and provides practical examples of using Nacos as both a service registry and a configuration center in microservice projects.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Why Nacos Beats Eureka: Hands‑On Guide to Service Discovery, Config Center & Cluster

1. Nacos Advantages

问题,既然有了Eureka ,为啥还要用Nacos?

Nacos serves as a core service registration and discovery center for microservices, offering a new choice beyond Eureka and Consul. It is ready to use out of the box, easy to get started, and has shown no major pitfalls so far.

1.1 Comparison with Eureka

1. Eureka 2.0 is closed source. 2. According to the official website, Nacos registers more instances than Eureka. 3. Nacos uses the Raft protocol, giving its cluster consistency far higher than Eureka's.

Raft, a distributed consistency protocol published in 2013, has become popular due to its relative simplicity and ease of implementation compared with other algorithms.

Raft Data Consistency Strategy The Raft protocol heavily relies on a Leader node to ensure cluster data consistency. Client data first reaches the Leader, which marks it as uncommitted, then replicates it to all Followers. After receiving acknowledgments from a majority of Followers, the Leader marks the data as committed and notifies the client, finally informing all Followers of the committed state.

1.2 Comparison with Spring Cloud Config

Three Major Advantages

Spring Cloud Config typically uses Git; dynamic changes still require Spring Cloud Bus to propagate changes to all clients.

Spring Cloud Config does not provide a visual interface.

Nacos Config uses long connections for updates, notifying providers instantly and outperforming Spring Cloud Config by a large margin.

2. Spring Cloud Alibaba Suite

The current Spring Cloud Alibaba suite mainly includes three components:

Nacos: a dynamic service discovery, configuration management, and service management platform for building cloud‑native applications.

Sentinel: protects service stability from traffic control, circuit breaking, and system load perspectives.

AliCloud OSS: Alibaba Cloud Object Storage Service, a massive, secure, low‑cost, highly reliable cloud storage solution.

Comparison between Spring Cloud Alibaba and Spring Cloud Netflix Suites

By examining component functionalities, the correspondence is roughly:

Nacos = Eureka/Consul + Config + Admin

Sentinel = Hystrix + Dashboard + Turbine

Dubbo = Ribbon + Feign

RocketMQ = RabbitMQ

Schedulerx = Quartz

AliCloud OSS, AliCloud SLS are unique; tracing (Sleuth, Zipkin) may be integrated into Sentinel.

3. Nacos Architecture and Installation

3.1 Nacos Architecture

The diagram shows that Nacos integrates service registration, discovery, configuration, and management functions, essentially a combination of Eureka/Consul + Config + Admin.

Besides Spring Cloud integration, Nacos can also be integrated with plain Spring and Spring Boot.

In this tutorial we focus only on Spring Cloud integration.

3.2 Download and Install Nacos Server

Before using Nacos, download it and start the Nacos Server.

Installation reference tutorial: https://www.cnblogs.com/crazymakercircle/p/11992539.html

4. Running Nacos Server

4.1 Two Modes

Nacos Server can run in two modes:

standalone

cluster

4.2 Standalone Mode

This mode is typically used for demos and tests; no configuration changes are needed. Execute the following command: sh bin/startup.sh -m standalone On Windows: cmd bin/startup.cmd -m standalone Then open http://cdh1:8848/nacos/index.html to see the console.

Default username and password are nacos nacos.

4.3 Cluster Mode

For production environments, use cluster mode.

Cluster mode requires MySQL and modifications to two configuration files:

conf/cluster.conf
conf/application.properties

In cluster.conf list the IPs of the machines that will run Nacos Server:

192.168.100.155
192.168.100.156

In application.properties add MySQL settings:

db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root

Create a database named nacos_config and import the tables from conf/nacos-mysql.sql.

4.4 Where Does Nacos Server Store Configuration Data?

问题来了: Nacos Server 的配置数据是存在哪里呢?

Without any custom configuration, Nacos stores data in two possible locations:

Memory

Local database

After restarting the server, the previously added nacos.properties configuration persists, indicating it is not stored in memory.

Inspecting NACOS_PATH/data reveals a derby-data directory where the configuration data is stored.

Derby is a Java‑written open‑source database from the Apache project.

If you switch the data source to MySQL, it works as well, but MySQL 8.0 is not supported.

Note: MySQL 8.0 is not supported.

Key points:

standalone uses Derby even if MySQL is configured; cluster mode automatically uses MySQL and will error if MySQL is not configured.

Example cluster.conf:

#it is ip
#example
10.10.109.214
11.16.128.34
11.16.128.36

After completing the configuration, start Nacos Server to see the effect.

5. Practical Example 1: Using Nacos as a Service Registry

Project Structure

The demo project has the following directory layout:

5.1 How to Use Nacos Client Component

First, import the Spring Cloud Alibaba BOM

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4.RELEASE</version>
    <relativePath/>
</parent>
<properties>
    <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    <spring-cloud-alibaba.version>0.2.0.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Version incompatibilities may arise; for example, Spring Boot 2.0.6.RELEASE throws

java.lang.NoClassDefFoundError: org/springframework/core/env/EnvironmentCapable

.

5.2 Demo Module Structure

The service registry and discovery are provided by Nacos Server; we only need to register services.

Two services are simulated: provider and consumer.

alibaba
├── service-provider-demo
│   ├── pom.xml
│   └── src
└── service-consumer-demo
    ├── pom.xml
    └── src

5.3 Provider Microservice

step1: Add dependencies to the provider and consumer pom files

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

step2: Main class

package com.crazymaker.cloud.nacos.demo.starter;

import com.crazymaker.springcloud.standard.context.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.List;

@EnableSwagger2
@SpringBootApplication
@EnableDiscoveryClient
@Slf4j
public class ServiceProviderApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(ServiceProviderApplication.class, args);
        Environment env = applicationContext.getEnvironment();
        String port = env.getProperty("server.port");
        String path = env.getProperty("server.servlet.context-path");
        System.out.println("
--------------------------------------
\t" +
                "Application is running! Access URLs:
\t" +
                "Local: \t\thttp://localhost:" + port + path + "/index.html
\t" +
                "swagger-ui: \thttp://localhost:" + port + path + "/swagger-ui.html
\t" +
                "----------------------------------------------------------");
    }
}

step3: Rest service interface

package com.crazymaker.cloud.nacos.demo.controller;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/echo")
public class EchoController {
    // Echo service
    @RequestMapping(value = "/{string}", method = RequestMethod.GET)
    public String echo(@PathVariable String string) {
        return "echo: " + string;
    }
}

step4: Configuration file

spring:
  application:
    name: service-provider-demo
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_SERVER:cdh1:8848}
server:
  port: 18080

step5: After starting, access via Swagger UI

5.4 Consumer Microservice Demonstrating RPC Remote Call

In NacosConsumerApplication integrate RestTemplate and Ribbon.

@LoadBalanced
@Bean
public RestTemplate restTemplate() {
  return new RestTemplate();
}

Consumer controller class

package com.crazymaker.cloud.nacos.demo.consumer.controller;

import com.crazymaker.cloud.nacos.demo.consumer.client.EchoClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/echo")
@Api(tags = "Service - Consumer")
public class EchoConsumerController {

    @Resource
    EchoClient echoClient;

    @ApiOperation(value = "Consume echo service interface")
    @RequestMapping(value = "/{string}", method = RequestMethod.GET)
    public String echoRemoteEcho(@PathVariable String string) {
        return "provider echo is:" + echoClient.echo(string);
    }
}

Consumer configuration file

spring:
  application:
    name: sevice-consumer-demo
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
server:
  port: 18081

Swagger UI for consumer

Remote echo API results:

5.5 Demo URLs

Provider:

http://localhost:18080/provider/swagger-ui.html#/Echo_%E6%BC%94%E7%A4%BA

Consumer:

http://localhost:18081/consumer/swagger-ui.html#/服务-消费者/echoRemoteEchoUsingGET

Nacos console:

http://cdh1:8848/nacos/index.html#/serviceManagement?dataId=&group=&appName=&namespace=

5.6 Nacos Console

The console displays the list of registered services and their details.

6. Practical Example 2: Using Nacos as a Configuration Center

6.1 Basic Concepts

1. Profile

Java projects often have multiple profiles (dev, test, pre‑prod, prod) each represented by a separate properties or YAML file. The active profile is selected via spring.profiles.active.

spring:
  application:
    name: sharding-jdbc-provider
  jpa:
    hibernate:
      ddl-auto: none
      dialect: org.hibernate.dialect.MySQL5InnoDBDialect
      show-sql: true
  profiles:
    active: sharding-db-table

Nacos Config moves these files into a unified configuration center, enabling real‑time updates.

2. Data ID

Each profile corresponds to a Data ID in Nacos. The naming format is ${prefix}-${spring.profiles.active}.${file-extension}.

Prefix defaults to spring.application.name but can be set via spring.cloud.nacos.config.prefix. spring.profiles.active provides the environment name.

File extension is configurable via spring.cloud.nacos.config.file-extension.

3. Group

The default group is DEFAULT_GROUP; it can be changed with spring.cloud.nacos.config.group to avoid name collisions.

After configuration, use @RefreshScope and @Value as with Spring Cloud Config.

6.2 Add Configuration via Nacos Console

Create two Data IDs: nacos-config-demo-dev.yaml for the development environment. nacos-config-demo-test.yaml for the test environment.

Both are created through the Nacos configuration UI (screenshots omitted).

6.3 Use Nacos Config Client Component

1. Add dependency

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>${nacos.version}</version>
</dependency>

2. Main class

package com.crazymaker.cloud.nacos.demo.consumer.starter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@EnableSwagger2
@EnableDiscoveryClient
@Slf4j
@SpringBootApplication(
        scanBasePackages = {
                "com.crazymaker.cloud.nacos.demo",
                "com.crazymaker.springcloud.standard"
        },
        exclude = {SecurityAutoConfiguration.class,
                // exclude DB auto‑configuration
                DataSourceAutoConfiguration.class,
                DataSourceTransactionManagerAutoConfiguration.class,
                HibernateJpaAutoConfiguration.class,
                // exclude Redis auto‑configuration
                RedisAutoConfiguration.class,
                RedisRepositoriesAutoConfiguration.class})
@EnableFeignClients(basePackages = {"com.crazymaker.cloud.nacos.demo.consumer.client"})
public class ConfigDomeProviderApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = null;
        try {
            applicationContext = SpringApplication.run(ConfigDomeProviderApplication.class, args);
            System.out.println("Server startup done.");
        } catch (Exception e) {
            log.error("服务启动报错", e);
            return;
        }
        Environment env = applicationContext.getEnvironment();
        String port = env.getProperty("server.port");
        String path = env.getProperty("server.servlet.context-path");
        System.out.println("
----------------------------------------------------------
\t" +
                "Application is running! Access URLs:
\t" +
                "Local: \t\thttp://localhost:" + port + path + "/index.html
\t" +
                "swagger-ui: \thttp://localhost:" + port + path + "/swagger-ui.html
\t" +
                "----------------------------------------------------------");
    }
}

3. Controller to read configuration

package com.crazymaker.cloud.nacos.demo.config.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/config")
@Api(tags = "Nacos Configuration Center Demo")
public class ConfigGetController {

    @Value("${foo.bar:empty}")
    private String bar;

    @Value("${spring.datasource.username:empty}")
    private String dbusername;

    @ApiOperation(value = "Get configuration value of bar")
    @RequestMapping(value = "/bar", method = RequestMethod.GET)
    public String getBar() {
        return "bar is :" + bar;
    }

    @ApiOperation(value = "Get DB username from configuration")
    @RequestMapping(value = "/dbusername", method = RequestMethod.GET)
    public String getDbusername() {
        return "db username is :" + dbusername;
    }
}

4. bootstrap.yml

spring:
  application:
    name: nacos-config-demo-provider
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_SERVER:cdh1:8848}
      config:
        server-addr: ${NACOS_SERVER:cdh1:8848}
        prefix: nacos-config-demo
        group: DEFAULT_GROUP
        file-extension: yaml
server:
  port: 18083
  servlet:
    context-path: /config

6.4 Test Result

Start the application and open Swagger UI at http://localhost:18083/config/swagger-ui.html#.

The API returns the expected configuration values:

6.5 Mapping Configuration Files

Use config.prefix to map the main configuration file.

Use spring.cloud.nacos.config.ext-config to map additional files, e.g.:

spring:
  application:
    name: nacos-config-demo-provider
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_SERVER:cdh1:8848}
      config:
        server-addr: ${NACOS_SERVER:cdh1:8848}
        prefix: nacos-config-demo
        group: DEFAULT_GROUP
        file-extension: yaml
        ext-config:
          - data-id: crazymaker-db-dev.yml
            group: DEFAULT_GROUP
            refresh: true
          - data-id: crazymaker-redis-dev.yml
            group: DEFAULT_GROUP
            refresh: true
          - data-id: crazymaker-common-dev.yml
            group: DEFAULT_GROUP
            refresh: true
          - data-id: some.properties
            group: DEFAULT_GROUP
            refresh: true

After starting, the application can retrieve values from these additional Data IDs.

7. Configuration Isolation

Real‑world applications often require isolation across environments, projects, and modules.

Development, test, pre‑production, and production environments need separation.

Different projects need isolation.

Within the same project, different modules need isolation.

Three mechanisms provided by Nacos achieve isolation:

Server address: spring.cloud.nacos.config.server-addr Namespace (use the namespace ID, not the name): spring.cloud.nacos.config.namespace Group:

spring.cloud.nacos.config.group

8. Nacos Cluster Setup

In cluster mode, an external database (MySQL) is required for shared data.

Cluster deployment can be fronted by Nginx for load balancing:

IP Planning

For a quick local test, copy the Nacos package into three directories (e.g., nacos, nacos1, nacos2) and modify the ports.

Edit conf/application.properties to use MySQL:

# Specify MySQL as the data source
spring.datasource.platform=mysql

# Database instance count
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

Change server.port for the additional instances (e.g., 8847 and 8846).

Initialize the database using conf/nacos-mysql.sql.

Rename conf/cluster.conf.example to conf/cluster.conf and list the three nodes:

127.0.0.1:8848
127.0.0.1:8847
127.0.0.1:8846

Start each instance with ./startup.sh; the default mode is cluster.

Cluster Usage

Nacos cluster can be accessed in four ways:

Direct IP: http://ip1:port/openAPI VIP (high availability): http://VIP:port/openAPI Domain name: http://nacos.com:port/openAPI Reverse proxy:

http://proxy:port/openAPI
Reverse proxy example using Nginx:
upstream nacos_server {
  server 127.0.0.1:8848;
  server 127.0.0.1:8847;
  server 127.0.0.1:8846;
}

server {
  listen 8648;
  server_name localhost;
  location / {
    proxy_pass http://nacos_server;
    index index.html index.htm;
  }
}

Accessing the cluster via the proxy (e.g., http://localhost:8648/nacos/#/clusterManagement) shows the cluster management UI.

Even if one Nacos node is killed, the service continues to operate, demonstrating high availability.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

service discoveryNacosClusterSpring Cloud AlibabaConfiguration Center
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.