Symfony性能优化_启用OPcache和缓存【技巧】

5次阅读

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

Symfony性能优化_启用OPcache和缓存【技巧】

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.solinux/macos)或 extension=php_opcache.dllwindows)已取消注释且路径正确
  • 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-datanginx)和 CLI 用户对 var/cache 有读写权限,推荐用 setfacl 而非 chmod 777
  • 生产环境禁用 debug 模式:检查 APP_DEBUG=0kernel.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_driverquery_cache_driver 默认仍走 filesystem,得单独覆盖为 pool: cache.app
  • Twig 编译缓存(twig.cache_dir)不能直接用 Redis,它依赖文件系统,但可设为 NULL 让 Twig 用 cache.app 存模板字节码
  • 本地开发可用 cache.adapter.Array(内存型),但仅限单请求生命周期,上线前必须切回持久化适配器

OPcache 配置调得太激进,导致 Symfony 热更新失效或白屏

opcache.validate_timestamps=0opcache.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 目录的属主开始查。

text=ZqhQzanResources