opcache 为什么会加快php的效率。 php 属于解释型语言,每次执行都要经过解释器来进行翻译 形成字节码,而应该程序定型了之后基本是就不会进行变化的。
而opcache就把这个内容缓存到内存中。降低了重复没有必要的劳动,进行减负。
什么是OpCache
将PHP代码预编译生成的脚本文件 Opcode 缓存在共享内存中供以后反复使用,从而避免了从磁盘读取代码再次编译的时间消耗。同时,它还应用了一些代码优化模式,使得代码执行更快。从而加速PHP的执行。
PHP的正常执行流程如下
request请求(nginx,apache,cli等)-->Zend引擎读取.php文件-->扫描其词典和表达式 -->解析文件-->创建要执行的计算机代码(称为Opcode)-->最后执行Opcode--> response 返回 每一次请求PHP脚本都会执行一遍以上步骤,如果PHP源代码没有变化,那么Opcode也不会变化,显然没有必要每次都重新生成Opcode,结合在Web中无所不在的缓存机制,我们可以把Opcode缓存下来,以后直接访问缓存的Opcode岂不是更快。
启用Opcode缓存之后的流程图如下所示:
Opcode cache 的目地是避免重复编译,减少 CPU 和内存开销。
安装
opcache只能在编译PHP的时候开启(OPcache 只能编译为共享扩展),加入 --enable-opcache选项来开启。
编译完成后,在php.ini文件中开启扩展
zend_extension=opcache.so
配置调整&优化
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=7963
opcache.validate_timestamps=0
具体参数的调整还是要配置具体项目测试调整参数。
memory_consumption
OPcache 的共享内存大小,以兆(M)为单位。
不同项目消耗的的大小都不同。
使用opcache_get_status函数来获取使用的内存数据来计算实际的值。
结果数组中的memory_usage返回了内存的消耗值。
计算公式:
( used_memory + free_memory + wasted_memory) / 1048576
array(4) {
["used_memory"]=>
int(68917520)
["free_memory"]=>
int(65300208)
["wasted_memory"]=>
int(0)
["current_wasted_percentage"]=>
float(0)
}
(68917520+65300208+0) / 1048576 = 128
我的项目就设置为
memory_consumption = 128
interned_strings_buffer
用来存储预留字符串的内存大小,以兆字节为单位。
PHP使用了一种叫做字符串驻留(string interning)的技术来改善性能。例如,如果你在代码中使用了1000次字符串“aabbcccdd”,在PHP内部只会在第一次分配一个内存区域来储存该字符串,剩下的999次将使用内存指针来引用该字符串。
默认情况中,这个优化只会存在于单个PHP-FPM进程中,如果设置了这个选项,将会在所有 PHP-FPM 进程中共享。在比较大的项目中,这可以非常有效地节约内存,提高应用的性能。
该选项默认值为8MB,我们可以根据项目的规模和实际情况来调整这个数值。
max_accelerated_files
该选项是用来控制内存中可以换成多少个文件。一般这个数是要大于你项目的总文件数,服务器内存也要够大。参考的文章都说要在质数集合中找打大于项目文件的数{ 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987 } ,配置文件中有说明设置大小的范围在200-1000000之间
我本地查询项目文件数为4632,就选择了7963这个质数。
> find . -type f -print | grep php | wc -l
4632
刷新缓存时间的设置
validate_timestamps和revalidate_freq 是用来控制缓存刷新的。
在生产环境中最好把validate_timestamps设置为0,不自动刷新缓存每次更新代码时候用脚本来刷新,validate_timestamps禁用后revalidate_freq选项也会失效。
清除缓存的方法
在生产环境为了提高性能一般是不开启自动刷新缓存的,每次更新时要如何刷新缓存,下面汇总了几种方法。
重启php-fpm:
- 优点:简单粗暴
- 缺点:重启的瞬间请求都会挂掉,小流量的网站还好,大型网站一般不敢这么干的,所以只有个人项目一般才这么干
调用函数清除缓存:
使用opcache_reset()方法也可以删掉缓存。
- 优点:不用重启php-fpm,方法是内置的函数,用来方便
- 缺点:没啥缺点吧
使用第三方工具:
在网上搜到了一个开源的工具:cachetool
- 优点:不用重启php-fpm,工具还提供了很多查看状态的方法。
- 缺点:要下载软件,也不算是缺点了吧。。