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.
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.
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.
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: false5.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=DEVWhen 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: beijing7.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-18. 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: 500mApply 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
