webman 的 config() 函数不支持热更新,因其启动时一次性加载并缓存配置文件,需自行实现带版本比对的单例配置中心,通过 apollo /notifications/v2 长轮询监听变更、拉取新值并重建 pdo 等依赖对象。

Webman 本身不支持运行时热更新配置,config() 函数读取的是启动时加载的 PHP 文件快照,改了 Apollo 配置,config('database.host') 还是旧值 —— 想“动态生效”,必须绕过框架默认行为,自己接管配置访问链路。
为什么 config() 永远不会自动刷新
Webman 的 config() 是纯静态函数:它在 Worker 启动时一次性 require 所有 config/*.php 文件并缓存结果。没有监听器、没有版本比对、不感知外部变更。哪怕你用 cURL 把 Apollo 的新配置拉下来,只要没手动 reload FPM 或重启 Worker,config() 就永远返回最初那批数组。
常见翻车点:
- 在控制器里写
config('app.debug')并指望它随 Apollo 变更而变 → 实际不变 - 把
config('database')直接传给 PDO 构造函数 → 连接参数固化,改了配置也连不到新地址 - 加了 APCu 缓存但没配失效逻辑 → 缓存过期前,新配置根本进不来
必须用单例封装 + 版本号比对
要让 Webman “感知” Apollo 变更,得自己实现一套带本地版本管理的配置中心单例,不能依赖 config()。核心是两个动作:轮询变更通知 + 拉取并覆盖内存配置。
关键实操建议:
- 用 Apollo 的
/notifications/v2接口做长轮询(不是 GET /configs),每次请求必须带lastNumber头,响应体是变更的 namespace 列表,不是配置内容本身 - 本地必须维护一个
$localVersion(初始为 0),每次收到通知后,再逐个调/configs/{appId}/{cluster}/{namespace}拉新值,并更新该 namespace 对应的本地版本号 - 不要在每个请求里都轮询 —— 启动一个独立的 Swoole Timer(如每 30 秒)去跑监听逻辑,避免阻塞 HTTP 请求
- 所有配置访问必须走你的单例方法,比如
ConfigCenter::get('database.host'),内部会先检查本地缓存是否过期(基于 TTL 或版本号)
数据库等依赖对象必须支持重建
PHP 没有 Spring 的 Environment 抽象层,PDO、Redis 客户端这类对象一旦初始化就绑定参数。Apollo 配置变了,你不主动销毁并重建,它们就永远用旧连接。
具体怎么做:
- 把数据库连接封装成可重入的工厂类,例如
DatabaseFactory::makeFromConfig(),每次需要时按当前配置生成新 PDO 实例 - 在 ConfigCenter 单例里加
onUpdate()回调钩子,当检测到database.*变更时,触发unset($pdo)并清空连接池缓存 - Webman 的
process或server配置不支持 reload,所以别试图热更新这些项;只管业务级配置(如cache.ttl、feature.flag) - 如果用了 Swoole 进程常驻特性,记得监听
SIGUSR1信号作为兜底手动重载入口,避免轮询失效时完全卡死
别在 PHP-FPM 环境里硬刚长轮询
Webman 基于 Swoole,能 hold 住长连接,但如果你误用 PHP-FPM 模式部署(比如 nginx + php-fpm),那所有轮询请求都会被进程生命周期截断 —— 超时、连接复用失败、频繁 502 是必然结果。
真实约束条件:
- 必须运行在 Swoole Worker 模式下(
php start.php start),且worker_num > 1保证监听不单点故障 - 轮询间隔设为 1000–5000ms,太短压垮 Apollo,太长延迟高;Apollo 默认限流 100 QPS/实例,别用多个 Worker 同时轮同一个 namespace
- 禁止用
file_get_contents()或简单curl_exec()做同步轮询 —— 必须用Swoole\Coroutine\Http\Client发起协程 HTTP 请求,否则阻塞整个 Worker - 首次启动时,先同步拉一次全量配置填充本地缓存,再启动长轮询,避免冷启动期间配置为空
最易被忽略的一点:Apollo 的 ReleaseKey 和 notifications/v2 的 lastNumber 不是同一套机制,混用会导致永远收不到通知;必须严格按文档用 lastNumber 做版本比对,且每次成功响应后立即更新它 —— 漏一次,后续所有变更就静默丢失。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











