Designing and Using a Configuration Center (Apollo) for Microservices
This article explains why a configuration center is essential for modern micro‑service architectures, describes the typical architecture and governance capabilities of Apollo, details its high‑availability and real‑time mechanisms, and showcases practical use cases such as feature switches, service governance, dynamic logging, routing, and data‑source management.
With the rapid growth of micro‑services, the number of applications and machines increases dramatically, making configuration management increasingly complex. Traditional approaches using static files or databases can no longer meet requirements such as real‑time updates, gray‑release, multi‑environment and cluster management, and robust permission and audit mechanisms.
A configuration center emerges as a solution, acting as the "brain" of micro‑services by allowing dynamic, centralized control of configuration values.
Why a configuration center is needed
Configuration as control: changes to configuration instantly affect running services.
Governance: permissions, audit logs, gray‑release, rollback, and environment/cluster specific settings.
Micro‑service complexity: large numbers of services make manual file edits impractical.
Typical shape of a configuration center (using Apollo as an example)
Key governance capabilities include unified management of environments and clusters, support for gray‑release, rollback, and comprehensive permission and audit features.
High availability
The server side consists of a database, Config Service, and Admin Service, all stateless and registered with Eureka. A Meta Server abstracts service discovery, and both Config and Admin services can be deployed together in a single JVM for simplicity. Clients maintain long‑polling connections for push updates and also periodically pull configurations as a fallback.
Real‑time delivery
When a user publishes a configuration via the Portal, the Admin Service stores a ReleaseMessage in the database. Config Services scan this table, detect new messages, and notify connected clients, ensuring rapid propagation of changes.
Making micro‑services smarter
Various scenarios illustrate how a configuration center can enhance intelligence:
Feature switches (release, experiment, ops) for controlled roll‑outs and A/B testing.
Service governance such as rate limiting and black/white‑list controls.
Database migration strategies using read/write switches.
Dynamic log level adjustment via listeners:
@ApolloConfigChangeListener
private void onChange(ConfigChangeEvent changeEvent) {
refreshLoggingLevels(changeEvent.changedKeys());
}
private void refreshLoggingLevels(Set<String> changedKeys) {
boolean loggingLevelChanged = false;
for (String changedKey : changedKeys) {
if (changedKey.startsWith("logging.level.")) {
loggingLevelChanged = true;
break;
}
}
if (loggingLevelChanged) {
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changedKeys));
}
}Dynamic routing in Spring Cloud Zuul:
@ApolloConfigChangeListener
public void onChange(ConfigChangeEvent changeEvent) {
boolean zuulPropertiesChanged = false;
for (String changedKey : changeEvent.changedKeys()) {
if (changedKey.startsWith("zuul.")) {
zuulPropertiesChanged = true;
break;
}
}
if (zuulPropertiesChanged) {
refreshZuulProperties(changeEvent);
}
}
private void refreshZuulProperties(ConfigChangeEvent changeEvent) {
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
this.applicationContext.publishEvent(new RoutesRefreshedEvent(routeLocator));
}Dynamic data‑source switching:
@Configuration
public class RefreshableDataSourceConfiguration {
@Bean
public DynamicDataSource dataSource(DataSourceManager dataSourceManager) {
DataSource actualDataSource = dataSourceManager.createDataSource();
return new DynamicDataSource(actualDataSource);
}
}
public class DynamicDataSource implements DataSource {
private final AtomicReference<DataSource> dataSourceAtomicReference;
public DynamicDataSource(DataSource dataSource) {
dataSourceAtomicReference = new AtomicReference<>(dataSource);
}
public DataSource setDataSource(DataSource newDataSource) {
return dataSourceAtomicReference.getAndSet(newDataSource);
}
@Override
public Connection getConnection() throws SQLException {
return dataSourceAtomicReference.get().getConnection();
}
// ... other methods ...
}Best practices cover public component configuration via shared namespaces, gray‑release procedures, and mandatory release audits to prevent accidental production incidents.
In conclusion, the article outlines why a configuration center is indispensable, demonstrates Apollo’s architecture and high‑availability design, and provides concrete examples of how dynamic configuration can make micro‑services more intelligent, reliable, and easier to operate.
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.
Ctrip Technology
Official Ctrip Technology account, sharing and discussing growth.
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.
