Mastering Apollo: A Deep Dive into Ctrip’s Open‑Source Distributed Configuration Center

This article walks through the concepts, architecture, and hands‑on steps for using Apollo, Ctrip’s open‑source distributed configuration center, covering project setup, Spring Boot integration, dynamic updates, clustering, namespaces, high‑availability design, and Kubernetes deployment.

Architect's Guide
Architect's Guide
Architect's Guide
Mastering Apollo: A Deep Dive into Ctrip’s Open‑Source Distributed Configuration Center

1. Core Concepts

Apollo is an open‑source configuration management system developed by Ctrip that centralizes configuration for multiple environments, clusters, and namespaces, supporting real‑time updates, gray releases, and fine‑grained permissions.

1.1 Background

As applications grow, the number of configuration items and the need for dynamic, environment‑specific settings increase, making traditional file‑based or database configurations insufficient.

1.2 Features

Simple deployment

Gray release support

Version management

Open API platform

Client configuration monitoring

Native Java and .NET clients

Real‑time hot updates

Permission and audit mechanisms

Unified management across environments and clusters

1.3 Basic Model

(1) User modifies and publishes a configuration in the Apollo portal.

(2) Config Service notifies Apollo clients of the change.

(3) Clients pull the latest configuration and apply it.

2. Apollo Architecture

The system consists of Config Service (reads/pushes configs) and Admin Service (modifies/publishes configs). Both are stateless and register to Eureka; a Meta Server abstracts service discovery. Clients obtain service lists via the Meta Server and communicate directly with Config Service instances.

Apollo basic architecture
Apollo basic architecture

3. Client Design and Update Mechanism

Clients maintain a long‑lived HTTP connection (implemented with HTTP long‑polling) to receive push notifications. If no change occurs within 60 seconds, the server returns 304; otherwise, the client immediately pulls the updated namespace.

The client also performs periodic pulls (default every 5 minutes) which can be tuned via apollo.refreshInterval.

On each pull the server returns 304 if the version has not changed.

Apollo client workflow
Apollo client workflow

4. High‑Availability Considerations

Both Config Service and Admin Service are stateless; losing a single instance has no impact because other instances take over. The system tolerates full data‑center outages by falling back to local cache files.

5. Practical Spring Boot Integration

5.1 Maven Dependency

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

5.2 Application.yml Configuration

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

5.3 Test Controller

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

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

5.4 Application Entry Point

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

5.5 Running the Application

When launching from an IDE, add JVM arguments:

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

When using java -jar, the same arguments apply.

6. Demonstrating Dynamic Updates

Access http://localhost:8080/test – the value comes from Apollo (e.g., 123456).

Modify the test key in Apollo and publish; the endpoint instantly reflects the new value (e.g., 666666).

Rollback the change in Apollo; the endpoint reverts to the previous value.

Simulate a config‑service outage by pointing -Dapollo.configService to a wrong address; the client falls back to the local cache and still returns the last known value.

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

Delete the key from Apollo; the endpoint again returns the default value.

7. Exploring Clusters and Namespaces

7.1 Environment Switching

Set apollo.meta to the PRO environment URL and launch with -Denv=PRO to fetch production configurations.

7.2 Cluster Selection

Define apollo.cluster (e.g., beijing or shanghai) to retrieve cluster‑specific values.

apollo:
  cluster: beijing

7.3 Namespace Selection

Configure apollo.bootstrap.namespaces to a private namespace such as dev-1 or dev-2 to isolate settings per application.

apollo:
  bootstrap:
    namespaces: dev-1

8. Deploying to Kubernetes

8.1 Dockerfile

FROM openjdk:8u222-jre-slim
VOLUME /tmp
ADD target/*.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS="-XX:MaxRAMPercentage=80.0 -Duser.timezone=Asia/Shanghai"
ENV APP_OPTS=""
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS"]

8.2 Kubernetes Manifests

Service (NodePort) and Deployment expose the application and inject the required environment variables.

apiVersion: v1
kind: Service
metadata:
  name: springboot-apollo
spec:
  type: NodePort
  ports:
  - name: server
    nodePort: 31080
    port: 8080
    targetPort: 8080
  selector:
    app: springboot-apollo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-apollo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: springboot-apollo
  template:
    metadata:
      labels:
        app: springboot-apollo
    spec:
      containers:
      - name: springboot-apollo
        image: mydlqclub/springboot-apollo:0.0.1
        ports:
        - containerPort: 8080
          name: server
        env:
        - name: JAVA_OPTS
          value: "-Denv=DEV"
        - name: APP_OPTS
          value: "--app.id=apollo-demo \
                 --apollo.bootstrap.enabled=true \
                 --apollo.bootstrap.eagerLoad.enabled=false \
                 --apollo.cacheDir=/opt/data/ \
                 --apollo.cluster=default \
                 --apollo.bootstrap.namespaces=application \
                 --apollo.autoUpdateInjectedSpringProperties=true \
                 --apollo.meta=http://service-apollo-config-server-dev.mydlqcloud:8080"
        resources:
          limits:
            memory: 1000Mi
            cpu: 1000m
          requests:
            memory: 500Mi
            cpu: 500m

Apply with kubectl apply -f springboot-apollo.yaml -n mydlqcloud and access the service via the NodePort (e.g., http://192.168.2.11:31080/test).

9. Conclusion

The tutorial demonstrates how Apollo provides a robust, real‑time configuration solution for Java microservices, covering basic concepts, client integration, dynamic updates, clustering, namespace isolation, and production‑grade Kubernetes deployment.

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.

distributed systemsJavaKubernetesConfiguration ManagementSpring BootApollo
Architect's Guide
Written by

Architect's Guide

Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.

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.