hyperf 3.1 启动慢、注解不生效等问题主因是注解缓存配置不当与启动路径未优化;开发环境需关闭注解缓存('cacheable' => false),生产环境须按清缓存→装依赖→预扫描→启动四步操作,缺一不可。

Hyperf 3.1 项目上线后启动变慢、改了注解不生效、本地调试快但生产环境反复重启失败——这些问题几乎都指向注解缓存配置不当与启动路径未优化,而非代码逻辑本身。
为什么注解缓存必须关掉开发环境
开发时若开启注解缓存('cacheable' => true),修改控制器上的#[GetMapping]或#[Controller]后,服务不重启就不会重新扫描,路由永远404。Hyperf 不会自动监听文件变化刷新缓存,它只在首次启动时生成runtime/annotations目录下的序列化文件。
确认是否关闭:打开config/autoload/annotations.php,将'cacheable'设为false。
【切记:此配置仅对开发环境生效,生产环境必须设为true】
生产环境注解缓存怎么开才安全
生产环境开启注解缓存能提升启动速度30%以上,但前提是缓存必须“干净”且“可复用”。直接php bin/hyperf.php start会导致缓存残留旧类路径或已删除的注解,引发Class not found或路由缺失。
正确操作顺序:
- 执行
rm -rf runtime/annotations/ runtime/container/ runtime/cache/ - 运行
composer install --no-dev(确保无开发依赖干扰反射) - 执行
php bin/hyperf.php gen:scan,显式触发注解预扫描并写入缓存 - 最后执行
php bin/hyperf.php start
这四步缺一不可。跳过第③步,容器会边启动边扫描,失去缓存意义;跳过第①步,旧缓存可能覆盖新结构,导致注入失败。
启动性能卡点排查三连问
如果按上述流程仍启动缓慢(>8秒),立即检查以下三项:
第一问:Swoole 协程是否真启用?运行php --ri swoole,确认输出中support coroutines => enabled。若为disabled,说明加载了系统自带非协程版swoole.so,需卸载重装pecl版。
第二问:DI 容器是否在反复解析?升级到hyperf/di:^3.1.18后,旧代码里带无类型提示的构造函数参数(如public function __construct($logger))会被直接跳过,容器报Entry "X" does not exist并降级尝试反射,拖慢启动。必须补全类型声明。
第三问:有没有在config/autoload/里误加了全盘扫描路径?比如'paths' => ['app']会扫描整个app目录,含tests、migrations等非运行时代码,反射耗时翻倍。应精确限定为['app/Controller', 'app/Service', 'app/Model']。
两种强制加速启动的硬核方式
方法一:禁用注解扫描(适用于纯路由配置场景)
若项目完全不用#[GetMapping]等注解,而是走config/routes.php硬编码路由,可直接删掉config/autoload/annotations.php文件。Hyperf 启动时将跳过整个注解模块,节省2~4秒。
方法二:预热容器(适用于高频变更业务)
在CI/CD流水线最后一步加入:php bin/hyperf.php di:preload。该命令会提前加载所有服务定义并生成runtime/container/preload.php,下次启动直接require该文件,绕过动态反射,实测启动时间压至1.2秒内。
注意:di:preload要求PHP ≥ 8.1且opcache.enable=1,否则会报错退出。











