OPcache未生效需先确认是否真正加载:检查CLI与FPM各自php.ini中extension=opcache.so是否启用,避免仅配置CLI;注意Symfony开发时CLI热加载绕过OPcache,生产环境须禁用debug、确保cache目录权限正确、合理设置opcache.validate_timestamps等参数。

OPcache没生效?先确认它真在跑
很多 Symfony 项目配了 opcache.enable=1 就以为完事,结果 phpinfo() 里看不到 OPcache 模块,或者 opcache_get_status() 返回空数组——根本没加载。常见原因是 CLI 和 FPM 使用不同 php.ini,而开发时只改了 CLI 的配置。
- 用
php -i | grep opcache查 CLI 是否启用 - 用
php-fpm -i | grep opcache(或访问/phpinfo.php)查 Web 环境 - 确认
extension=opcache.so(Linux/macOS)或extension=php_opcache.dll(Windows)已取消注释且路径正确 - Symfony 开发环境常走 CLI(如
bin/console),但热加载、Profiler 会绕过 OPcache 缓存字节码,别拿debug:config cache的结果判断 OPcache 效果
Symfony 缓存目录权限不对,cache:warmup 直接失败
执行 php bin/console cache:warmup --env=prod 报错 Failed to write cache file,不是代码问题,而是 var/cache/prod 目录归属或 SELinux 上的限制挡住了 PHP 进程写入。
- 确保 Web 服务器用户(如
www-data或nginx)和 CLI 用户对var/cache有读写权限,推荐用setfacl而非chmod 777 - 生产环境禁用
debug模式:检查APP_DEBUG=0和kernel.debug=false,否则缓存键带调试信息,无法复用 - 别在
prod环境下留着cache:clear自动触发 warmup 的钩子——它可能用 CLI 用户身份执行,和 Web 进程用户不一致 - 若用 Docker,确认
var/cache卷挂载后权限未被重置,chown -R www-data:www-data var/cache在 entrypoint 里跑一次更稳
cache.adapter.filesystem 在高并发下变慢?换 cache.adapter.redis
默认的文件系统缓存适配器在大量请求时会因磁盘 I/O 和文件锁拖慢响应,尤其当缓存项多、频繁写入(比如 Twig 模板编译、Doctrine 元数据缓存)时,stat() 和 flock() 成为瓶颈。
- Redis 不仅快,还能自动处理缓存失效、TTL 和原子操作;Symfony 原生支持,只需配
cache.dsn=redis://localhost - 注意 Doctrine 的
metadata_cache_driver和query_cache_driver默认仍走 filesystem,得单独覆盖为pool: cache.app - Twig 编译缓存(
twig.cache_dir)不能直接用 Redis,它依赖文件系统,但可设为null让 Twig 用cache.app存模板字节码 - 本地开发可用
cache.adapter.array(内存型),但仅限单请求生命周期,上线前必须切回持久化适配器
OPcache 配置调得太激进,导致 Symfony 热更新失效或白屏
把 opcache.validate_timestamps=0 和 opcache.revalidate_freq=0 一加,确实快了,但改了 PHP 文件后必须重启 PHP-FPM 才生效,CI/CD 自动部署时容易漏掉这步,线上就白屏或报 Class not found。
- 生产环境建议保留
opcache.validate_timestamps=1,配合opcache.revalidate_freq=60(每分钟检查一次),平衡性能与可维护性 -
opcache.max_accelerated_files必须大于项目实际 PHP 文件数(含 vendor),find src/ vendor/ -name "*.php" | wc -l算一下,再乘 1.5 倍,设太小会导致文件被踢出缓存 -
opcache.memory_consumption默认 128M 往往不够,vendor 里一堆类,建议至少 256M;用opcache_get_status()['memory_usage']观察使用率 - 修改 OPcache 配置后,
systemctl reload php*-fpm不一定生效,有些系统要restart,用opcache_get_status()['opcache_enabled']确认是否真重启了
缓存链路越长,某一处权限、路径或时间戳配置不对,就卡在某个环节不动——与其猜哪一步错了,不如从 OPcache 状态和 var/cache/prod 目录的属主开始查。











