opcache的原理
1、Opcache是什么?
Opcache是一种通过将解析的PHP脚本预编译的字节码(Operate Code)存放在共享内存中来避免每次加载和解析PHP脚本的开销(中间码(也叫操作码)已经在内存),解析器可以直接从共享内存读取已经缓存的字节码(Operate Code),从而大大提高PHP的执行效率。
解释性语言(比如php,需要zend引擎解释器,不产生机器码,而是产生中间码,通过zend解释器来执行)和编译性语言(编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件)
opcache更新不及时
解决方案
(一)、设置Opcache脚本验证时间
可以通过更改 Opcache 以下两个配置选项来调整代码重载时间
opcache.revalidate_freq=0 检查脚本时间戳是否有更新的周期,以秒为单位。(如果设置为 0 会导致针对每个请求, OPcache 都会检查脚本更新)
opcache.validate_timestamps=0 如果启用,那么 OPcache 会每隔 opcache.revalidate_freq 设定的秒数 检查脚本是否更新。
PS:在实际生产环境中,为了尽可能达到最优性能,尽量不开启文件更新验证,因为每次验证都会重新预编译PHP代码到共享内存中。
(二)、重启 | 重载 php-fpm 进程
直接重启php-fpm
(三)、手动清理缓存
(三)、手动清理缓存
除了上面的两种方式,还有更为稳妥一点的缓存清理,我们可以通过opcache_reset()和opcache_invalidate() 函数来刷新Opcache缓存。
opcache_reset()- 重置整个Opcode缓存,所有的PHP脚本将会被重新解析再预编译为Opcode。
opcache_invalidate() - 清除指定脚本缓存,可以传递两个参数,一个是刷新文件路径,一个是force字段, 如果 force 没有设置或者传入的是 FALSE,那么只有当脚本的修改时间 比对应Opcode的时间更新时,脚本的缓存才会失效。
需要注意的是,当PHP以PHP-FPM的方式运行的时候,opcache的缓存是无法通过php命令进行清除的,只能通过http或cgi到php-fpm进程的方式来清除缓存,我们可以编写一个对外接口,来达到清理缓存的目的。
相关实现如下(框架:laravel):
Route::any('cache-reset', function () {
//重置整个Opcode缓存
dd(opcache_reset());
});
Route::any('cache-update', function () {
//清除掉最近一次更新文件的缓存
exec('git diff --name-only HEAD~ HEAD', $output);
foreach ($output as $file) {
$path = base_path($file);
opcache_invalidate($path, true);
}
dd('刷新完成');
});
参考文章:
https://blog.csdn.net/weixin_39685578/article/details/112050196