代码文件已经更新,页面和异常堆栈却仍指向旧行号,甚至刷新后时新时旧。这通常不是 Magento Cache,而是 PHP OPcache、长生命周期进程、符号链接发布方式或多节点版本不一致。
先固定复现条件和影响范围
给本次构建记录不可变版本号,在响应头或健康页输出不敏感的 build ID 和节点名。对比 Web PHP 与 CLI PHP 的版本、php.ini 和实际 release 路径。
readlink -f /var/www/current
php -i | grep -E 'opcache.validate_timestamps|opcache.revalidate_freq|opcache.enable_cli'
php-fpm -i 2>/dev/null | grep -E 'opcache.validate_timestamps|opcache.revalidate_freq'
ps -eo pid,lstart,cmd | grep '[p]hp-fpm'
sha256sum app/etc/config.php composer.lock
根据证据分支定位
只有 Web 请求旧而 CLI 新,检查 FPM OPcache 和进程;只有队列消费者旧,说明长进程未重启;刷新随机切换版本,说明负载均衡后节点或 release symlink 不一致。validate_timestamps 关闭时,仅替换文件不会使缓存自动失效。
修复时保留回滚路径
使用原子 release 切换,发布完成后按运维策略平滑 reload PHP-FPM 并重启 Magento 长进程;所有节点部署同一构建。不要从 Web 请求暴露 opcache reset 端点,也不要在高峰粗暴 kill 全部进程。
上线验收
连续请求覆盖所有节点,build ID、堆栈行号和行为必须一致;运行 Cron、消费者与后台任务验证新代码。下一次回滚也应按同样流程切换并刷新进程缓存。
生产环境操作前的检查
处理“Magento 2 发布后 PHP 仍执行旧代码”前,先记录 Magento 版本、部署模式、问题 Store View、复现时间和最近一次发布。所有 SQL 默认先执行 SELECT;任何写操作、目录清理或配置切换都应确认影响范围、保留备份并准备回滚。多节点环境要核对各节点代码版本、app/etc/env.php 配置摘要与流量分布。
php bin/magento --version
php bin/magento deploy:mode:show
php bin/magento maintenance:status
php bin/magento indexer:status
php bin/magento cache:status
命令应由 Magento 文件所有者在项目根目录执行。不要在生产高峰同时运行全量索引、静态部署和数据修复;涉及客户、支付、税费或订单的改动,先在脱敏数据副本验证。
建立可比较的排查记录
每次实验只改变一个变量,记录操作前值、命令、开始与结束时间、结果和回滚方式。准备一个正常对象与一个异常对象对照;若旧对象恢复而新对象仍能复现,说明根因尚未消除。
| 检查层 | 需要保存的证据 | 通过标准 |
|---|---|---|
| 入口层 | URL、状态码、请求 ID、节点 | 路由和协议一致 |
| 应用层 | 异常堆栈、模块、作用域 | 无新异常且可重复 |
| 数据层 | 主键、时间、关联行数 | 关系完整且无重复副作用 |
| 业务层 | 正常、失败、重试路径 | 最终结果一致 |
修复后的观察窗口
上线后至少观察一轮 Cron、队列和索引周期,并在两台节点、无痕浏览器和目标 Store View 重复验证。临时调试日志必须脱敏,确认错误率、响应时间和数据量稳定后及时关闭。

