上星期源里的php升到了5.5版,于是apc光荣的下岗了。不过新版php自带了opcache,直接用上,很好很强大。
但是不久就发现piwik的dashboard页面会导致segfault,其他界面和其他网站都没问题。其实piwik的dashboard页面一直有问题,还在用apc的时候就只有少数几个版本的apc可以使用,其余都会导致segfault。但是piwik官方认为segfault属于php的bug,所以他们不会修。只好暂时关闭opcache了。
不用缓存跑了两天,php-fpm内存使用飙升。于是装上xcache。但是不知道是不是兼容php5.5版的xcache是dev阶段的原因,内存占用还是很高。大致来说,其他条件都一样的情况下,我开了20个php-fpm进程,不用任何缓存比用opcache内存占用多了100M,而使用xcache的话比不用缓存还要多40~50M。所以看来必须使用opcache了。
于是只好在php.ini里乱改乱改,最后发现如果把opcache.optimization_level
改成0x00000000
,可以禁用optimization,这时候piwik就不会出错了。但是因为找不到说明文档,所以不知道除了完全禁用外能不能使用其他等级,不过我暂时没发现禁用后对性能有什么影响。
opcache默认的opcache.revalidate_freq
是2
,所以是每两秒钟才会验证一下php文件是否更新,而之前php-apc是每个request都验证。降低验证频率的好处是性能更好,节省资源,但坏处是如果是采用了php文件保存一些数据,同时这些数据又经常变动,那就有很大可能会得到过期的数据。所以要不就是把opcache.revalidate_freq
改成0,要不就修改php程序,强制使缓存过期
if (@filemtime($php_file) && function_exists('opcache_invalidate'))
opcache_invalidate($php_file,true);
Update 2013-08-28:
发现如果php文件被删除了,执行opcache_invalidate会导致php-fpm coredump,而且如果已经缓存了,file_exists的结果会为真,但其实php文件已经不存在了,所以就不能用file_exists作为是否执行opcache_invalidate的判断。可以用@filemtime来判断。filemtime不是读取文件内容,所以总是直接读取原php文件,如果不存在了就返回false,但是同时也会给出warning,所以用@忽略warning。