Apollo客户端本地缓存默认强制启用,网络中断时自动降级读取磁盘缓存文件;加载优先级为:内存快照→本地磁盘缓存→JVM/Spring Boot fallback配置,网络请求失败即跳过,不阻塞不报错。

Apollo 客户端在生产环境网络中断时,默认就开启本地容灾缓存读取——它不是“需要开启”的功能,而是设计上强制启用的兜底行为。你不需要改任何开关,只要客户端成功初始化过一次,本地缓存目录(如 ~/opt/data/{appId}/config-cache)里有合法文件,网络断开后所有 Config.getProperty() 调用都会自动降级到磁盘缓存,返回上次拉取到的值。
为什么网络断了还能读到配置?看缓存加载顺序
Apollo 启动和运行时按固定优先级加载配置,网络只是其中一环:
- 第一优先级:内存中已加载的配置快照(来自上次成功刷新)
- 第二优先级:本地磁盘缓存文件(
~/opt/data/{appId}/config-cache下的.properties或.yaml文件) - 第三优先级:JVM 系统属性或 Spring Boot 的
application.properties中的 fallback 配置(仅限 bootstrap 阶段) - 网络请求是“尝试性”的——失败即跳过,不阻塞、不抛异常、不中断流程
也就是说,只要应用曾成功启动过一次(哪怕只是本地调试),缓存文件就已生成;之后即使 apollo.meta 地址全不可达,ConfigService.getConfig("application") 仍能返回有效值。
常见误判:以为没走缓存,其实是没拉到正确 namespace
现象是网络断开后 @Value("${db.url}") 报 IllegalArgumentException: Could not resolve placeholder,但这通常不是缓存失效,而是根本没加载对应 namespace:
-
apollo.bootstrap.namespaces没显式声明非application的 namespace(比如漏了database.properties) - Portal 中该 namespace 的「格式」选错(如填了
database.properties却设为 YAML 格式) - namespace 名字大小写或点号不一致(
DB.Properties≠db.properties) - 本地缓存目录被清空或权限拒绝(检查
ls -l ~/opt/data/{appId}/config-cache)
验证方式:直接读磁盘文件,比如 cat ~/opt/data/your-app-id/config-cache/your-app-id+default+database.properties.properties,看内容是否存在且格式可解析。
如何确认当前读的是缓存而非远端?
不能靠“有没有报错”来判断,因为 Apollo 压根不报错。可靠方式只有两个:
- 打开 DEBUG 日志:
logging.level.com.ctrip.framework.apollo=DEBUG,观察是否持续出现Could not load config from server或no available server - 主动触发一次配置变更(比如在 Portal 修改一个 key),然后等 5 分钟,再检查应用日志里有没有
ConfigChangeEvent—— 如果一直没收到,基本说明长轮询已断,正在纯走缓存
注意:ConfigService.getRepository().isInited() 返回 true 并不代表网络通畅,只表示客户端完成初始化;真正的连接状态得靠日志或健康接口(如 /actuator/apollo)里的 hasRemoteConfig 字段。
真正容易被忽略的点是:缓存文件本身可能损坏或版本错乱。Apollo 不校验缓存文件完整性,如果磁盘被手动篡改、或进程异常退出导致写一半,下次启动可能静默加载空配置。上线前建议加个轻量校验脚本,读取缓存目录下关键 namespace 文件的 lastModified 时间戳和非空行数,作为基线备案。











