Comprehensive Guide to Using Ctrip's Apollo Distributed Configuration Center with Spring Boot
This article provides an in‑depth tutorial on Apollo, Ctrip's open‑source distributed configuration center, covering its concepts, architecture, four management dimensions, client design, deployment in Kubernetes, and step‑by‑step Spring Boot integration with code examples and configuration details.
大家好,我是不才陈某~
Today we dive into Ctrip's open‑source distributed configuration center Apollo, which rivals Nacos in functionality.
1. Basic Concepts
Apollo introduces many concepts; it is best to understand them before hands‑on practice.
1. Background
As applications grow more complex, the number of configuration items (feature toggles, parameters, server addresses, etc.) increases, demanding real‑time updates, gray releases, environment and cluster segregation, robust permission and audit mechanisms. Traditional file‑based or database configurations can no longer meet these needs, prompting the creation of Apollo.
2. Introduction
Apollo is an open‑source configuration management center developed by Ctrip's framework team, enabling centralized management of configurations across environments and clusters, with real‑time push, permission control, and workflow governance.
3. Features
Simple deployment
Gray release
Version management
Open API platform
Client configuration monitoring
Native Java and .Net clients
Hot‑update (real‑time push)
Permission, release audit, operation audit
Unified management of multi‑environment, multi‑cluster configurations
4. Core Model
The basic model consists of three steps:
(1) User modifies and publishes configuration in the center.
(2) The center notifies Apollo clients of updates.
(3) Clients pull the latest configuration, update local cache, and notify the application.
5. Four Dimensions of Apollo
Apollo supports four dimensions for managing Key‑Value configurations:
application (application)
environment (environment)
cluster (cluster)
namespace (namespace)
(1) application
The client needs to know its app.id to fetch the correct configuration.
(2) environment
Four default environments are provided:
FAT (Feature Acceptance Test)
UAT (User Acceptance Test)
DEV (Develop)
PRO (Produce)
The environment is set via the env variable.
(3) cluster
Clusters group instances of the same application, e.g., by data center (Shanghai vs. Beijing).
Configurations can differ per cluster.
(4) namespace
Namespaces separate configuration groups, similar to separate files (e.g., application.yml ). They can be public or private, with inheritance support.
6. Local Cache
Apollo client caches configurations locally to survive server outages or network issues. Default cache paths are /opt/data/{appId}/config-cache on Linux/macOS and C:\opt\data\{appId}\config-cache on Windows. Cached files follow the pattern {appId}+{cluster}+{namespace}.properties .
7. Client Design
The client maintains a long‑polling HTTP connection to receive push updates instantly. It also periodically pulls configurations as a fallback, defaulting to a 5‑minute interval, configurable via apollo.refreshInterval .
8. Overall Design
The architecture includes Config Service (provides read/push), Admin Service (handles modifications), Meta Server (service discovery via Eureka), and client load‑balancing.
9. Availability Considerations
Scenario
Impact
Degradation
Reason
One config service down
No impact
Stateless service, client reconnects to another instance
All config services down
Clients cannot read latest config; portal unaffected
Clients use local cache on restart
One admin service down
No impact
Stateless admin, portal reconnects
All admin services down
Clients unaffected; portal cannot update config
One portal down
No impact
SLB load‑balances across portals
All portals down
Clients unaffected; portal cannot update config
One data center down
No impact
Multi‑DC deployment with sync, Meta Server/Portal auto‑switch via SLB
2. Creating an Apollo Project and Configuration
Log in to Apollo (deployed via NodePort) with username apollo and password admin , create a project, and add a configuration key test with value 123456 . Publish the configuration.
3. Building a Spring Boot Client Project
1. Add Maven Dependency
<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<groupId>club.mydlq</groupId>
<artifactId>apollo-demo</artifactId>
<version>0.0.1</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>2. Add Configuration Parameters
# Application config
server:
port: 8080
spring:
application:
name: apollo-demo
# Apollo config
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: false3. 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;
}
}4. Application Entry
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. JVM Startup Parameters
For Kubernetes deployment, set:
-Denv=DEV (or PRO ) to select the environment.
-Dapollo.configService=http://192.168.2.11:30002 to specify the config service address.
$ java -Dapollo.configService=http://192.168.2.11:30002 -Denv=DEV -jar apollo-demo.jar4. Testing Scenarios
Access http://localhost:8080/test to see the value from Apollo ( 123456 ). Modify the value in Apollo to 666666 , republish, and the endpoint reflects the change instantly. Test rollback, service outage (client falls back to local cache), and deletion of the key (client returns the default value).
5. Exploring Cluster and Namespace
Demonstrates switching environments (PRO), clusters (beijing vs. shanghai), and namespaces (dev-1 vs. dev-2) by adjusting apollo.meta , apollo.cluster , and apollo.bootstrap.namespaces respectively, and observing the returned configuration values.
6. Deploying Spring Boot with Apollo on Kubernetes
1. Build Docker Image
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" ] $ docker build -t mydlqclub/springboot-apollo:0.0.1 .2. Kubernetes Deployment
apiVersion: v1
kind: Service
metadata:
name: springboot-apollo
spec:
type: NodePort
ports:
- name: server
nodePort: 31080
port: 8080
targetPort: 8080
- name: management
nodePort: 31081
port: 8081
targetPort: 8081
selector:
app: springboot-apollo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-apollo
labels:
app: springboot-apollo
spec:
replicas: 1
selector:
matchLabels:
app: springboot-apollo
template:
metadata:
name: springboot-apollo
labels:
app: springboot-apollo
spec:
restartPolicy: Always
containers:
- name: springboot-apollo
image: mydlqclub/springboot-apollo:0.0.1
imagePullPolicy: Always
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 $ kubectl apply -f springboot-apollo.yaml -n mydlqcloud3. Verify Deployment
Access the service via NodePort (e.g., http://192.168.2.11:31081/test ) and observe the configuration value retrieved from Apollo.
This concludes the tutorial.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
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.