Cloud Native 28 min read

Why We Dropped Nacos for Apollo: A Hands‑On Guide to Configuration Management

This article explains why the team replaced Nacos with Ctrip's open‑source Apollo configuration center, outlines Apollo's core concepts, features, and architecture, and provides step‑by‑step instructions for creating projects, testing dynamic updates, exploring environments, clusters, namespaces, and deploying a SpringBoot application on Kubernetes.

Java Architect Handbook
Java Architect Handbook
Java Architect Handbook
Why We Dropped Nacos for Apollo: A Hands‑On Guide to Configuration Management

1. Basic Concepts

Apollo is an open‑source configuration management center developed by Ctrip, designed to centralize configuration for multiple environments and clusters, support real‑time updates, gray releases, and fine‑grained permission and audit mechanisms.

1.1 Background

As applications grow more complex, traditional file‑based or database configurations cannot meet the demand for real‑time changes, gray releases, and multi‑environment management, prompting the creation of Apollo.

1.2 Introduction

Apollo provides centralized management of key‑value configurations across environments and clusters, with real‑time push capabilities.

1.3 Features

Simple deployment

Gray release support

Version management

Open API platform

Client configuration monitoring

Native Java and .NET clients

Hot (real‑time) updates

Permission management, release audit, operation audit

Unified management of different environments and clusters

1.4 Basic Model

The basic workflow consists of:

User modifies and publishes a configuration in the config center.

The config center notifies Apollo clients of the update.

Clients pull the latest configuration, update local cache, and notify the application.

Apollo basic model
Apollo basic model

1.5 Four Dimensions of Apollo

Apollo manages configurations across four dimensions:

application (app.id)

environment (FAT, UAT, DEV, PRO)

cluster (e.g., data‑center based groups)

namespace (logical grouping similar to separate config files)

1.6 Local Cache

Clients cache configuration files locally (e.g., /opt/data/{appId}/config-cache on Linux or C:\opt\data\{appId}\config-cache on Windows) to ensure availability when the server is unreachable.

{appId}+{cluster}+{namespace}.properties

1.7 Client Design

Clients maintain a long‑polling HTTP connection to receive push notifications. If no change occurs within 60 seconds, the server returns 304. Clients also periodically pull configurations as a fallback, typically every 5 minutes (configurable via apollo.refreshInterval).

1.8 Overall Design

Config Service handles read/push operations, Admin Service handles modifications, both are stateless and registered to Eureka. A Meta Server abstracts service discovery, and clients resolve service addresses via the Meta Server.

2. Creating an Apollo Project and Configuration

2.1 Login to Apollo

Access the Apollo portal (deployed via NodePort) with username apollo and password admin.

Login Apollo
Login Apollo

2.2 Modify Department Data

Since Apollo does not provide UI for department management, modify the ApolloPortalDB tables directly to add custom departments.

Modify department data
Modify department data

2.3 Create a Project

After updating the department data, create a new project with Application ID apollo-test and Application Name apollo-demo.

Create project
Create project

2.4 Create a Configuration Parameter

Add a key test with value 123456 and a remark, then save and publish.

Create configuration
Create configuration

3. Building an Apollo Client Demo

3.1 Add Maven Dependency

<dependency>
  <groupId>com.ctrip.framework.apollo</groupId>
  <artifactId>apollo-client</artifactId>
  <version>1.4.0</version>
</dependency>

3.2 Add Configuration to application.yml

apollo.meta

: Apollo server address apollo.cluster: Target cluster apollo.bootstrap.enabled: Enable Apollo apollo.bootstrap.namespaces: Namespaces to load (default application) apollo.cacheDir: Local cache directory apollo.autoUpdateInjectedSpringProperties: Whether Spring placeholders update at runtime apollo.bootstrap.eagerLoad.enabled: Load Apollo before logging initialization

server:
  port: 8080
spring:
  application:
    name: apollo-demo
app:
  id: apollo-test
apollo:
  cacheDir: /opt/data/
  cluster: default
  meta: http://192.168.2.11:30002
  autoUpdateInjectedSpringProperties: true
  bootstrap:
    enabled: true
    namespaces: application
  eagerLoad:
    enabled: false

3.3 Create Test Controller

@RestController
public class TestController {
    @Value("${test:默认值}")
    private String test;

    @GetMapping("/test")
    public String test() {
        return "test的值为:" + test;
    }
}

3.4 Create Application Entry

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3.5 JVM Parameters

When running in Kubernetes, set:

-Dapollo.configService=http://192.168.2.11:30002 -Denv=DEV

4. Running Tests

4.1 Verify Initial Value

Access http://localhost:8080/test – the response shows test的值为:123456, confirming the value comes from Apollo.

4.2 Update Value in Apollo

Change test to 666666 in the portal, publish, and refresh the endpoint – the response updates accordingly.

4.3 Rollback

After rolling back the configuration, the endpoint returns the previous value 123456.

4.4 Simulate Config Center Failure

Modify the JVM argument to point to an invalid address. The application still returns 123456 because the client falls back to the local cache.

Delete the cache files and restart; the endpoint now returns the default value defined in the @Value placeholder.

4.5 Delete Parameter

Removing the test key from Apollo causes the endpoint to fall back to the default value.

5. Exploring Environments, Clusters, and Namespaces

5.1 Different Environments

Configure a PRO environment in Apollo, add the same test key with a different value, and switch the client by setting env=PRO and updating apollo.meta. The endpoint then reflects the production value.

5.2 Different Clusters

Create clusters beijing and shanghai, each with distinct test values. By setting apollo.cluster to the desired cluster, the client retrieves the corresponding value.

5.3 Different Namespaces

Create private namespaces dev-1 and dev-2, each holding a different test value. Set apollo.bootstrap.namespaces to the target namespace to fetch its configuration.

6. Deploying a SpringBoot Application on Kubernetes with Apollo

6.1 Build Docker Image

Compile the project with Maven, create a Dockerfile that defines JAVA_OPTS (e.g., timezone) and APP_OPTS (Apollo parameters), and build the image:

$ mvn clean install
$ docker build -t mydlqclub/springboot-apollo:0.0.1 .

6.2 Kubernetes Deployment

Create a Service of type NodePort and a Deployment that sets the environment variables:

JAVA_OPTS="-Denv=DEV"
APP_OPTS="--app.id=apollo-demo --apollo.bootstrap.enabled=true ... --apollo.meta=http://service-apollo-config-server-dev.mydlqcloud:8080"

Apply the manifest:

$ kubectl apply -f springboot-apollo.yaml -n mydlqcloud

6.3 Test Deployed Service

Access the NodePort (e.g., http://192.168.2.11:31081/test) and verify the value 123456 is returned, confirming successful integration with Apollo in a Kubernetes environment.

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.

JavaMicroservicesKubernetesSpringBootApolloConfiguration Center
Java Architect Handbook
Written by

Java Architect Handbook

Focused on Java interview questions and practical article sharing, covering algorithms, databases, Spring Boot, microservices, high concurrency, JVM, Docker containers, and ELK-related knowledge. Looking forward to progressing together with you.

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.