昨晚线上出故障,紧急处理切换容灾后缓解了故障,解决故障后从容灾切换回正式服务时发现PHP文件更新无效,重启FPM后才生效。下面记录复盘追查的过程。php
由于是PHP文件更新不生效,因此立刻怀疑到opcache上面,到线上看了一眼php.ini,果真使用了opcache,而且检测间隔时间设置为60秒。查看昨晚的日志,更新不生效持续时间远远大于60秒,因此这个检测间隔时间的问题能够PASS了,咱们继续。服务器
在线上环境查看更新的文件和日志中的时间的时候,忽然发现PHP文件时间和日志中的时间对应不上,立刻找OP确认,OP交待说这个文件是回滚mv回来的,因此文件时间和我预期的不一致。我用stat命令看了一下,果真modify time相比access time早了一段时间,依据这点线索推测opcache依靠的是PHP文件的modify time做为文件被修改的检测条件。在线下复现问题,填坑成功!app
下面总结一下填坑过程当中查的一些相关的知识点函数
在php.ini中增长opcache时须要使用zend_extension,而不是extension,否则会获得如下WARNING性能
PHP Warning: PHP Startup: Invalid library (appears to be a Zend Extension, try loading using zend_extension=opcache.so from php.ini) in Unknown on line 0
使用下列推荐设置来得到较好的性能:日志
opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60 opcache.fast_shutdown=1 opcache.enable_cli=1
本次涉及到的有两个参数code
revalidate_freq,默认2
检查脚本时间戳是否有更新的周期,以秒为单位。 设置为 0 会致使针对每一个请求, OPcache 都会检查脚本更新string
validate_timestamps,默认1
若是启用,那么 OPcache 会每隔 opcache.revalidate_freq 设定的秒数 检查脚本是否更新。 若是禁用此选项,你必须使用 opcache_reset() 或者 opcache_invalidate() 函数来手动重置 OPcache,也能够 经过重启 Web 服务器来使文件系统更改生效。it
access time 表示咱们最后一次访问文件的时间
modify time 表示咱们最后一次修改文件的时间
change time 表示咱们最后一次对文件属性改变的时间,包括权限,大小,属性等等io
C/C++中也可使用stat方法查询文件的这3个时间属性,通常应用都会经过modify time判断文件是否更新,咱们本次踩坑就是由于文件是mv操做的,modity time没有更新,因此opcache没有更新。