Hyperf 不自动刷新 @Value 或 @ConfigurationProperties 注入值,需监听 ConfigChangedEvent 事件手动处理变更,并建议启用 LONG_POLLING 模式以降低延迟。

Hyperf 服务无法自动感知 Apollo 配置变更?不是 Apollo 没生效,而是 Hyperf 默认不触发 Spring Cloud 风格的 @RefreshScope 机制 —— 它走的是自己的驱动监听 + 事件广播路径。
Hyperf 的 ApolloDriver 不会自动重载 @Value 或 @ConfigurationProperties 注入的字段
Hyperf 的配置中心驱动(如 ApolloDriver)只负责把远端配置拉下来、合并进 Config 组件,并广播 ConfigChangedEvent。它不会像 Spring Boot 的 @RefreshScope 那样自动重建 Bean 或刷新字段值。
- 直接在 Controller/Service 中用
@Value("${xxx}")注入的值,启动后就固定了,Apollo 变更后不会更新 - 用
@ConfigurationProperties绑定的类,也不会自动 reload,除非你手动监听并重新绑定 - Hyperf 的
Config实例本身是单例且可 runtime 调用get(),所以最可靠的方式是「按需读取」而非「注入缓存」
正确做法:监听 ConfigChangedEvent 并手动刷新业务逻辑
Hyperf 提供了开箱即用的事件机制,你需要显式订阅配置变更事件,在回调中做你需要的操作:
- 监听事件:在任意
@Listener类中监听ConfigChangedEvent - 获取新值:通过
$event->getConfig()或直接调用config('key')读取最新配置 - 刷新资源:比如重置连接池、更新路由规则、清空本地缓存等
示例:
#[Listener]
class ApolloConfigListener implements ListenerInterface
{
public function listen(): array
{
return [ConfigChangedEvent::class];
}
public function process(object $event): void
{
if ($event instanceof ConfigChangedEvent && in_array('database.host', $event->getChangedKeys())) {
// 触发数据库连接池重建逻辑
Coroutine::create(function () {
DB::reconnect();
});
}
}
}
pull_mode 设为 PullMode::LONG_POLLING 才能接近实时生效
Hyperf Apollo 驱动支持两种拉取模式:INTERVAL(轮询)和 LONG_POLLING(长轮询)。默认是 INTERVAL,间隔由 interval 参数控制(单位秒),延迟明显。
-
PullMode::INTERVAL:每 N 秒发一次 HTTP 请求,适合低频变更或调试环境 -
PullMode::LONG_POLLING:客户端发起请求后,服务端保持连接直到有变更或超时(默认 60s),响应后立即发起下一轮 —— 延迟通常在 1~2 秒内 - 必须确保 Apollo 服务端开启长轮询支持(默认开启),且网络无代理截断长连接
配置示例(config/autoload/config_center.php):
'apollo' => [
'driver' => ApolloDriver::class,
'pull_mode' => PullMode::LONG_POLLING,
'server' => 'http://apollo-config-service:8080',
'appid' => 'hyperf-service',
'cluster' => 'default',
'namespaces' => ['application'],
],
跨服务同步的本质是「各自监听 + 同一命名空间 + 一致 namespace ID」
所谓“跨服务同步”,并不是某个服务把配置推给其他服务,而是所有服务都连接同一个 Apollo 实例、使用相同的 appid 和 namespace,靠 Apollo 的统一发布机制达成最终一致性。
- 不同服务只要配置相同的
appid(如user-service)和namespace(如application),就能读到同一份配置 - 修改 Apollo 控制台中该
namespace下的配置并发布,所有监听该 namespace 的 Hyperf 实例都会在几秒内收到ConfigChangedEvent - 不存在“主从同步”或“配置转发”,也不依赖服务间通信 —— 这正是配置中心解耦的关键
容易被忽略的一点:Hyperf 默认只监听 application namespace,如果你用了自定义 namespace(如 database.yaml),必须显式加进 namespaces 数组,否则不会拉取也不会触发事件。


















