谈谈 opcache 的一些碎杂事(一不当心服务器内存就撑爆了)php
在PHP的应用中,说到优化,不得不提到opcache,在PHP5.6+,咱们能够开启opcache来,提高咱们网站的访问速度,因此用好opcache能帮咱们提高效率。git
在opcache生效中,有两个主要配置github
opcache.validate_timestamps=1;web
opcache.revalidate_freq=10;api
1.当validate_timestamps设置0时, opcache.revalidate_freq的值将失效,validate_timestamps做用主要验证是否要从新生成缓存脚本,PHP将不会检测代码是否改变,这样会致使部署更新的代码后,不会自动生成新的缓存,就致使仍是显示原来的旧代码; 固然,能够设置为 0(这样性能最佳的),可是这个通常适合于不频繁更新的PHP 代码,每次更改后须要手动清除 opcache,即须要平滑加载php-fpm。缓存
2.当validate_timestamps设置1时,opcache.revalidate_freq的值将生效,在opcache.revalidate_freq设置的时间值,PHP将会从新生成代码缓存。bash
接下来看开启opcache 会致使什么问题服务器
首先,我在给两个在运行的PHP项目添加opcachecurl
配置ide
[opcache] zend_extension=opcache.so opcache.enable=1 opcache.memory_consumption=384 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=100000 opcache.max_wasted_percentage=5 opcache.use_cwd=1 opcache.validate_timestamps=1 opcache.revalidate_freq=60 opcache.save_comments=0 opcache.fast_shutdown=1 opcache.consistency_checks=0
项目一:是一个不多的代码更新的PHP项目(主机一)
项目二:是一个频繁更新的PHP项目,cli与php-fpm(主机二)
未开启前,查看两个主机的内存使用状况
主机一:
# free -m total used free shared buff/cache available Mem: 7774 1636 636 35 5500 5804 Swap: 0 0 0
主机二:
# free -m total used free shared buff/cache available Mem: 15830 6228 2765 1318 6836 7073 Swap: 5887 0 5887
两台配置opcache ,主机二频繁的跟新PHP代码 ,等了一段时间后再查看一下,
主机一:
# free -m total used free shared buff/cache available Mem: 7774 1641 630 37 5502 5797 Swap: 0 0 0
主机二:
# free -m total used free shared buff/cache available Mem: 15830 14202 339 11208 1288 298 Swap: 5887 0 5887
好家伙,主机二所在的内存使用,差点就满了,主机二所在的地方有比较多的PHP项目,看到这种状况,立马中止了opcache。
问题分析:为何会出现这种问题呢?
分析一:
可能因为个人PHP项目跟新代码的方式是经过软连所生成的web目录,opcache 是经过文件的真实路径进行缓存的,这就致使了每次部署都会生成缓存字节码,那么就致使了旧的缓存没有被清理,也致使咱们的内存没法释放,从而致使内存给撑满了。
分析二:
多是在 执行cli 命令行下执行此函数并不能清理 php-fpm 下生成的缓存字节码,也会大量产生缓存,会严重消耗内存、cpu。
问题处理:
按照分析是什么缘由引发,那就好处理了。
方法一:
平滑重启PHP,可是对于那些频繁跟新的PHP项目并非很实用,这里略过
方法二:
经过第三方库 cachetool工具,实现对缓存的刷新控制。
Cachetool工具使用
安装cachetool-4.1.1.phar ,版本 PHP >=7.1
下载安装:
curl -sO https://gordalina.github.io/cachetool/downloads/cachetool-4.1.1.phar chmod +x cachetool-4.1.1.phar mv cachetool-4.1.1.phar cachetool.phar
最新的能够下载:
curl -sO https://github.com/gordalina/cachetool/releases/latest/download/cachetool.phar chmod +x cachetool.phar
查看用法:
php /usr/local/cachetool/cachetool.phar --fcgi=/dev/shm/php-cgi.sock
注意:--fcgi参数配置主要为sock和127.0.0.1:9000两种
查看PHP的opcache的缓存状态:
php /usr/local/cachetool/cachetool.phar opcache:status --fcgi=/dev/shm/php-cgi.sock
清除PHP缓存:
php /usr/local/cachetool/cachetool.phar opcache:reset --fcgi=/dev/shm/php-cgi.sock
查看缓存是否已经被清理
之后用法,能够经过更新代码后更新缓存
问题再次出现
原本,觉得经过以上的方法,清理每一次上线的代码缓存,就不会致使内存挤满的,但是现实很打脸,内存大概10来分钟,又被挤满了,内存,cpu 直达100%,任何操做都作不了,被迫强制关机。
好了。咱们经常使用的php通常有两种运行方式,一种是php-fpm ,另外一种是cli,而我,偏偏忽略cli的运行方式。而Cli运行方式,也会加载读取php.ini配置文件,也会消耗内存。
处理办法:
找了不少的opcache配置解析,发现忽略一个很重要的一个参数opcache.enable_cli,好像发现了,就是这个致使的,这个就是致使cli,占用大量的内存,并且没法清理,而引发系统内存崩溃。
添加配置
opcache.enable_cli=0
使用命令获取内存使用状况
一直监控了好久,使用很正常,调试方向,没错了,
而最后接口返回时间对比一下
优化前
优化后
而经过curl获取点时间
curl -o /dev/null -s -w '%{time_connect}:%{time_starttransfer}:%{time_total}\n' 'http://api.test.com' 0.067740:0.097896:0.098095
总结:
在应用opccache中 。必定要把握opcache.enable_cli 配置参数的应用;而最后的实践对比验证也很重要了。