2. Apollo架构解析:Config Service、Admin Service、Portal、客户端SDK、Meta Server角色与交互流程
说实话,我第一次接触Apollo的时候,也被它那堆组件搞得有点懵。Config Service、Admin Service、Portal、客户端SDK,还有那个Meta Server……它们到底谁管谁?
别急,咱们一个一个拆开看。搞懂了这些角色的分工,你就能明白Apollo为什么能扛住生产环境的高并发。
2.1 五大核心角色,各司其职
Apollo的架构设计,说白了就是「读写分离」+「配置隔离」。我当年在团队里推Apollo的时候,最头疼的就是跟新人解释这几个服务的关系。后来我画了张图,大家一看就懂了。
核心角色一览:
- Config Service — 给客户端读配置的,无状态,可以随便横向扩展
- Admin Service — 给Portal写配置的,管理配置的增删改
- Portal — 管理后台,咱们操作配置的Web界面
- 客户端SDK — 嵌入业务应用里,负责拉配置、监听变化
- Meta Server — 服务发现中心,告诉客户端和Portal该找谁
2.2 Config Service — 客户端的「粮仓」
Config Service是Apollo里最忙的那个角色。它负责给客户端提供配置读取服务,说白了就是「你问我答」。客户端启动的时候,会先来找它要配置。
我记得有一次线上出问题,客户端老是拿不到最新配置。排查了半天,发现是Config Service的实例数不够,扛不住突发的长轮询请求。后来加了两个节点,问题立马解决。
我的经验:Config Service是无状态的,所以你可以放心地横向扩展。我一般建议至少部署2个节点,生产环境4个起步。别省这点机器,省了后面有你哭的。
2.3 Admin Service — 配置的「守门员」
Admin Service跟Config Service正好相反。它只处理写操作——创建命名空间、修改配置项、发布配置等等。这些操作都通过Portal来触发。
你想想看,如果读写混在一起,万一有人写配置的时候把服务搞挂了,那所有客户端都读不了配置,整个系统就瘫了。Apollo把读写分离,就是为了避免这种「一颗老鼠屎坏了一锅粥」的情况。
注意:Admin Service和Config Service虽然是两个独立的服务,但它们共享同一个数据库(ConfigDB)。所以数据库的高可用才是真正的命门。我曾经见过有人只给ConfigDB配了单机,结果磁盘坏了,整个Apollo都废了。一定要做主从或者集群!
2.4 Portal — 管理员的「驾驶舱」
Portal就是咱们平时在浏览器里打开的那个管理界面。创建项目、添加配置、灰度发布、权限管理……这些操作都在Portal上完成。
Portal只跟Admin Service通信,不直接操作数据库。这样做的好处是,万一Portal被攻击或者出了Bug,也不会影响到客户端的配置读取。
2.5 客户端SDK — 业务应用的「触角」
客户端SDK是嵌入到咱们业务代码里的。它负责两件事:
- 启动时拉取全量配置 — 应用启动的时候,SDK会从Config Service拉取所有配置,缓存在本地内存里
- 运行时监听变更 — 通过长轮询机制,实时感知配置变化,然后推送给业务代码
这里有个细节很多人会忽略:SDK拉配置的时候,会先问Meta Server「Config Service在哪」,而不是直接硬编码地址。这样做的好处是,Config Service的地址变了,客户端完全无感知。
2.6 Meta Server — 服务发现的「导航员」
Meta Server是Apollo里最轻量级的组件,但它承担着「指路」的重任。客户端和Portal启动的时候,第一件事就是找Meta Server要地址。
Meta Server内部维护了一份Config Service和Admin Service的地址列表。它通过Eureka(或者Nacos)来做服务注册与发现。
交互流程总结:
- 客户端启动 → 问Meta Server「Config Service在哪」 → 拿到地址 → 拉配置
- Portal操作 → 问Meta Server「Admin Service在哪」 → 拿到地址 → 写配置
- Admin Service收到写请求 → 写入ConfigDB → 通知Config Service刷新缓存
- Config Service感知到变化 → 通过长轮询推送给客户端SDK
2.7 一次完整的配置变更,到底经历了什么?
咱们来走一遍完整的流程。假设你在Portal上修改了一个配置项的值,然后点击「发布」:
- Portal向Meta Server询问Admin Service的地址
- Portal把修改请求发给Admin Service
- Admin Service把新配置写入ConfigDB
- Admin Service通知Config Service:「配置变了,刷新一下缓存」
- Config Service从DB重新加载配置到内存
- Config Service通过长轮询,把变更推送给所有在线的客户端SDK
- 客户端SDK收到通知,更新本地缓存,触发业务代码的回调函数
整个过程,从你点击发布到客户端感知到变化,正常情况下不超过1秒。我当年第一次测这个流程的时候,还以为是假的,结果日志一打,确实快。
避坑指南:我曾经遇到过一个问题——配置发布后,部分客户端迟迟收不到更新。后来发现是Config Service的长轮询超时时间设置得太短,导致连接频繁断开重连。建议把长轮询超时设为60秒,既能保证实时性,又不会给服务端太大压力。
2.8 一张表看懂各组件职责
| 组件 | 职责 | 有无状态 | 通信对象 |
|---|---|---|---|
| Config Service | 提供配置读取、长轮询推送 | 无状态 | 客户端SDK、Meta Server |
| Admin Service | 提供配置管理、发布、回滚 | 无状态 | Portal、Meta Server |
| Portal | Web管理界面 | 有状态(Session) | Admin Service |
| 客户端SDK | 嵌入业务应用,拉取/监听配置 | 有状态(本地缓存) | Config Service、Meta Server |
| Meta Server | 服务发现与路由 | 无状态 | 所有组件 |
嗯,到这里,Apollo的五大角色和它们的交互流程,你应该心里有数了。说白了,这套架构的核心思想就是「读写分离」+「服务发现」。搞懂了这些,后面咱们讲部署和调优的时候,你就能理解为什么每个组件要那样配置了。