Skip to content

Apollo — 分布式配置中心

架构设计

Apollo 是携程开源的分布式配置中心,专注于配置管理,提供完善的权限管控、灰度发布和审计功能。

┌──────────────────────────────────────────────────────────┐
│                    Apollo Portal(管理界面)               │
└──────────────────────┬───────────────────────────────────┘
                       │ 管理 API
┌──────────────────────▼───────────────────────────────────┐
│                  Apollo Config Service                    │
│  ┌─────────────┐  ┌──────────────┐  ┌─────────────────┐ │
│  │  配置读取    │  │  配置推送     │  │   灰度发布       │ │
│  └─────────────┘  └──────────────┘  └─────────────────┘ │
└──────────────────────┬───────────────────────────────────┘

┌──────────────────────▼───────────────────────────────────┐
│                    MySQL(配置存储)                       │
└──────────────────────────────────────────────────────────┘

客户端:
  App ──► Apollo Client ──[长轮询]──► Config Service
                        ──[本地缓存]──► 本地文件(降级)

核心概念

概念说明示例
AppId应用唯一标识order-service
Environment环境DEV/FAT/UAT/PRO
Cluster集群(同环境不同配置)default/beijing/shanghai
Namespace配置文件(类似文件)application/database/redis

配置优先级

远程配置(Apollo)> 本地配置文件(application.yml)

Spring Boot 集成

xml
<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-client</artifactId>
    <version>2.1.0</version>
</dependency>
properties
# application.properties
app.id=order-service
apollo.meta=http://apollo-config:8080
apollo.bootstrap.enabled=true
apollo.bootstrap.namespaces=application,database,redis.properties
# 开启启动阶段注入(确保 @Value 在 Bean 初始化前就有值)
apollo.bootstrap.eagerLoad.enabled=true
java
// 使用 @Value 注入(需配合 @RefreshScope 或 ApolloConfigChangeListener)
@Component
public class OrderConfig {
    
    @Value("${order.timeout:5000}")
    private int timeout;
    
    // 监听配置变更
    @ApolloConfigChangeListener(value = {"application", "database"})
    private void onChange(ConfigChangeEvent event) {
        event.changedKeys().forEach(key -> {
            ConfigChange change = event.getChange(key);
            log.info("Config changed: {} {} -> {}", 
                key, change.getOldValue(), change.getNewValue());
        });
        // 手动刷新 Bean(如果没有 @RefreshScope)
        refreshConfig();
    }
}

多 Namespace 使用

java
// 读取公共配置(跨应用共享)
@ApolloConfig("application")
private Config appConfig;

@ApolloConfig("common.properties")  // 公共 Namespace
private Config commonConfig;

@PostConstruct
public void init() {
    String dbUrl = commonConfig.getProperty("db.url", "default");
    String timeout = appConfig.getProperty("order.timeout", "5000");
}

灰度发布

Apollo 支持按 IP 灰度发布配置:

1. 在 Portal 创建灰度版本
2. 指定灰度 IP(如:192.168.1.100, 192.168.1.101)
3. 发布灰度版本
4. 验证灰度节点行为
5. 全量发布 或 回滚
java
// 客户端无需特殊处理,Apollo 自动根据 IP 下发对应配置
// 灰度节点收到灰度配置,其他节点收到正式配置

权限管控

Apollo 提供细粒度的权限控制:

权限说明
项目管理员管理项目成员、Namespace
发布权限可以发布配置(生产环境建议与编辑权限分离)
编辑权限可以修改配置,但不能发布
查看权限只读

最佳实践:生产环境配置编辑和发布权限分离,避免误操作。

配置加密

敏感配置(密码、密钥)建议加密存储:

java
// 使用 jasypt 加密
// 1. 加密配置值
String encrypted = jasypt.encrypt("my-db-password");
// 存储:ENC(加密后的值)

// 2. Apollo 中存储:db.password=ENC(xxxxx)

// 3. 客户端自动解密
@SpringBootApplication
@EnableEncryptableProperties
public class Application { }

高可用部署

生产环境推荐部署:
  Config Service × 3(无状态,可水平扩展)
  Admin Service × 2(无状态)
  Portal × 1(或 2,主备)
  MySQL × 1主1从(或 RDS)
  
  Config Service 前置 Nginx/SLB 负载均衡
nginx
# nginx.conf
upstream apollo-config {
    server apollo-config-1:8080;
    server apollo-config-2:8080;
    server apollo-config-3:8080;
}

故障处理案例

案例一:配置变更后客户端未更新

排查

bash
# 检查客户端长轮询是否正常
# 客户端日志关键字
grep "Loaded config for namespace" application.log
grep "Config changed" application.log

# 检查 Config Service 是否正常
curl http://apollo-config:8080/health

常见原因

  • 客户端与 Config Service 网络不通
  • apollo.meta 配置错误
  • 客户端版本过旧,不支持长轮询

案例二:本地缓存导致读取旧配置

现象:Config Service 不可用时,客户端读取本地缓存文件,但缓存文件是旧版本。

本地缓存位置

/opt/data/{appId}/config-cache/{appId}+{cluster}+{namespace}.properties

处理

  • 正常情况:Config Service 恢复后,客户端自动同步最新配置
  • 紧急情况:手动更新本地缓存文件,重启应用

案例三:数据库连接池耗尽

现象:Apollo Config Service 响应慢,日志出现数据库连接超时。

解决

properties
# Config Service 数据库连接池配置
spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.connection-timeout=30000

与 Nacos 配置中心对比

维度ApolloNacos
定位专注配置管理配置 + 服务发现
权限管控细粒度(编辑/发布分离)基础权限
灰度发布原生支持(按 IP)支持 Beta 发布
审计日志完整操作记录基础日志
多环境原生多环境命名空间隔离
配置格式Properties/XML/JSON/YAML/TXTProperties/YAML/JSON/TEXT
适用场景大型团队,权限要求高中小团队,一站式

PaaS 中间件生态系统深度学习文档