Appearance
Apollo 详解:携程配置中心
Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中管理不同环境、不同集群的配置,配置修改后实时推送到应用端。它是国内最流行的开源配置中心之一,与 Nacos、Spring Cloud Config 并称三大配置方案。
一、为什么需要 Apollo?
1.1 配置管理的痛点
没有配置中心的典型问题:
1. 配置散落在各处:application.yml、启动参数、数据库、硬编码
2. 修改配置需要重启:改一个超时时间,需要重新部署整个服务
3. 环境配置混乱:dev 的数据库地址不小心部署到生产
4. 配置变更无记录:谁改了、什么时候改的、改了什么,全不知道
5. 权限无法控制:所有人都能改配置,误操作风险极高1.2 Apollo 如何解决
┌──────────────────────────────────────────────────────────────────┐
│ Apollo 配置中心 │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Apollo Portal(管理界面) │ │
│ │ │ │
│ │ 环境管理 集群管理 命名空间 权限管理 发布历史 灰度发布 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Apollo 核心服务(Config/Admin/Portal) │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Config │ │ Admin │ │ Portal │ │ │
│ │ │ Service │ │ Service │ │ Service │ │ │
│ │ │ 配置读取 │ │ 配置修改 │ │ 管理界面 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ │ ★ 通过 Eureka 注册发现,Config Service 可横向扩展 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ DEV 环境 │ │ TEST 环境 │ │ PROD 环境 │ │
│ │ order- │ │ order- │ │ order- │ │
│ │ service │ │ service │ │ service │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ★ 配置修改后实时推送到客户端,无需重启应用 │
│ ★ 发布历史可追溯,支持一键回滚 │
│ ★ 权限控制:谁可以改、谁可以发布,精细化管理 │
└──────────────────────────────────────────────────────────────────┘二、核心概念
| 概念 | 说明 | 示例 |
|---|---|---|
| 应用(AppId) | 配置的最小管理单元 | order-service |
| 环境(Env) | 部署环境,物理隔离 | DEV / TEST / PROD |
| 集群(Cluster) | 一个环境下的不同分组 | default、shanghai、beijing |
| 命名空间(Namespace) | 配置的分类 | application(公共)、数据库(私有) |
| 配置项(Item) | 具体的 key-value | timeout=3000 |
| 发布(Release) | 配置生效的操作 | 修改后必须发布才能生效 |
| 灰度发布 | 只对部分实例生效 | 先灰度 10% 实例,验证后再全量 |
配置层级:
AppId(应用)
└── Env(环境)
└── Cluster(集群)
└── Namespace(命名空间)
└── Item(配置项)
├── key: timeout
├── value: 3000
└── comment: 超时时间三、Apollo 特色功能
3.1 全中文管理界面
Apollo 提供功能完善的管理界面,支持配置的增删改查、发布、回滚、权限管理、灰度发布等,体验优于 Config 和 Nacos。
3.2 发布回滚
配置修改流程:
1. 管理员在 Portal 修改配置 → 保存
2. 配置进入"未发布"状态
3. 点击"发布" → 配置推送到 Config Service
4. Config Service 通知所有客户端
5. 客户端实时更新配置
回滚流程:
1. Portal 查看发布历史
2. 选择要回滚的版本
3. 点击"回滚" → 一键恢复到历史版本3.3 灰度发布
灰度发布流程:
1. 创建灰度配置(如 timeout=5000)
2. 选择灰度规则:
- 按 IP 灰度:只对 192.168.1.10, 192.168.1.11 生效
- 按百分比灰度:只对 10% 的实例生效
3. 灰度发布
4. 验证灰度效果
5. 全量发布 或 放弃灰度3.4 权限管理
角色权限:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 管理员 │ │ 编辑者 │ │ 观察者 │
│ (Master) │ │ (Editor) │ │ (Viewer) │
├─────────────┤ ├─────────────┤ ├─────────────┤
│ 增删改查 │ │ 增删改查 │ │ 仅查看 │
│ 发布 │ │ 保存 │ │ │
│ 回滚 │ │ │ │ │
│ 权限管理 │ │ │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
★ 发布和保存分离:编辑者可以修改配置,但只有管理员才能发布
★ 多环境权限隔离:DEV 的编辑者不一定能操作 PROD3.5 配置继承
公共命名空间(application):
timeout = 3000
retry = 3
订单服务私有命名空间(order-service):
timeout = 5000 ← 覆盖公共配置
max.thread = 10
最终生效:
timeout = 5000 ← 私有覆盖公共
retry = 3 ← 继承公共
max.thread = 10 ← 私有独有四、快速上手
4.1 部署 Apollo
bash
# 快速启动(开发环境)
git clone https://github.com/apolloconfig/apollo.git
cd apollo/scripts
./start.sh4.2 依赖
xml
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>2.2.0</version>
</dependency>4.3 配置
yaml
# application.yml
app:
id: order-service # 应用 ID,与 Apollo 中一致
apollo:
meta: http://localhost:8080 # Apollo Config Service 地址
bootstrap:
enabled: true # 启用 Apollo 引导
namespaces: application,数据库配置 # 加载的命名空间
cache-dir: /opt/data/apollo-cache # 本地缓存目录4.4 使用配置
java
// 方式一:@Value(支持动态刷新)
@RestController
public class OrderController {
@Value("${order.timeout:3000}")
private int timeout;
@GetMapping("/timeout")
public String getTimeout() {
return "当前超时时间:" + timeout;
}
}
// 方式二:API 方式(获取最新配置)
@Autowired
private Config config; // com.ctrip.framework.apollo.Config
public void doSomething() {
String timeout = config.getProperty("order.timeout", "3000");
int retryCount = config.getIntProperty("order.retry", 3);
// 监听配置变更
config.addChangeListener(changeEvent -> {
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
log.info("配置变更: {} = {} -> {}", key, change.getOldValue(), change.getNewValue());
}
});
}五、Apollo vs Nacos vs Config
| 维度 | Apollo | Nacos | Spring Cloud Config |
|---|---|---|---|
| 出品方 | 携程 | 阿里巴巴 | Spring 官方 |
| 配置存储 | MySQL | MySQL(内置 Derby) | Git / SVN / Native |
| 配置推送 | HTTP 长轮询(1s) | 长轮询 + UDP | 需配合 Bus + MQ |
| 管理界面 | ✅(功能最完善) | ✅(功能完善) | ❌(无原生界面) |
| 灰度发布 | ✅(原生支持) | ✅(支持) | ❌ |
| 权限管理 | ✅(编辑/发布分离) | ✅(RBAC) | ❌ |
| 版本管理 | ✅(发布历史 + 回滚) | ✅(历史版本) | ✅(Git 天然版本) |
| 多环境 | ✅(DEV/TEST/PROD) | ✅(Namespace) | ✅(Profile) |
| 部署复杂度 | 高(Config + Admin + Portal + MySQL) | 低(单机可运行) | 中(Config Server + Git) |
| 学习成本 | 中 | 低 | 中 |
| 适用场景 | 企业级配置管理,需要精细化权限 | 阿里云生态,一站式 | 简单配置管理,Git 强绑定 |
选型建议:
需要强大的权限管理 + 灰度发布 → Apollo
Spring Cloud Alibaba 生态,一站式 → Nacos
简单配置管理 + 不想引入额外组件 → Config + Git
需要精细化的发布审批流程 → Apollo(编辑/发布分离)六、面试要点
Q1:Apollo 的配置实时推送是怎么实现的?
Apollo 客户端通过 HTTP 长轮询(Long Polling)向 Config Service 发起请求,Config Service 持有请求 60 秒。如果配置有变更,立即返回;如果无变更,超时后客户端重新发起长轮询。这样既保证了实时性,又避免了频繁轮询。
Q2:Apollo 的编辑和发布为什么要分离?
防止误操作。编辑者可以修改配置并保存,但只有管理员才能发布。这就像代码的 PR 机制:开发者可以提交代码,但上线需要审批。生产环境配置变更风险高,需要审批流程。
Q3:Apollo 和 Nacos 怎么选?
需要精细化权限管理、灰度发布、发布审批流程选 Apollo;需要注册中心 + 配置中心一体化、阿里云生态、轻量部署选 Nacos。Apollo 功能更完善,Nacos 部署更简单。
Q4:Apollo 客户端获取不到配置怎么办?
Apollo 有本地缓存机制。首次启动时,如果连接不上 Config Service,会读取本地缓存目录的配置。如果本地缓存也没有,会使用 classpath 下的 META-INF/app.properties 中的兜底配置。多层容错保证服务能启动。
