互联网有很多讨论,在CLI中调用apc_cache_clear()
不会清除“web”PHP进程中的操作码缓存,无论它们是在Apache内部运行还是由FPM运行(参见How to clear APC cache entries?)。作为建议的解决方案,可以创建一个调用apc_cache_clear()
的简单PHP页面,并从CLI调用它。 Symfony's ApcBundle就是这么做的。
如果来自CLI的apc_cache_clear()
没有从Apache / FPM清空缓存,那么它是否在FPM工作者之间?如果我通过HTTP调用/clear_apc_cache.php,它只由一个FPM工作进程运行。那么,APC操作码缓存真正是否在池和工作人员之间共享 - 更具体:它是否会自动从所有工作人员中清除?
答案 0 :(得分:23)
所有php-fpm工作者共享与父php-fpm进程相同的操作码缓存; source。如果你有一个/apc_clear_cache.php文件并且通过HTTP调用它(使用像curl这样的东西),你将使用相同的php-fpm主进程清除所有worker的操作码缓存。
这个blog article非常好地解释了apc如何工作以及如何在发布期间有效地清除它。
答案 1 :(得分:11)
如果直接通过FastCGI界面执行脚本,则可以通过cli清除操作码缓存,而无需将文件部署到您的网站。
我创建了this gist,您可以在服务器上使用它来清除php5-fpm缓存。
如果您使用的是unix套接字:
php clear-apc.php --sock /var/run/php5-fpm.sock
否则:
php clear-apc.php --port=[port]
或省略默认127.0.0.1:9000
答案 2 :(得分:3)
我刚刚发现不同的池也共享相同的APC缓存,至少在PHP 5.4中使用FPM以及操作码缓存内容。
这是我注意到的:
我已经设置了多个PHP-FPM池,每个池都在/srv/www/domain.com/目录下chroot。
PHP脚本的主要位置是/srv/www/domain.com/docroot /.
现在,如果我创建一个文件/srv/www/domain_1.com/docroot/test.php,并加载脚本,它会显示它应该显示的内容。
但是,当我创建文件/srv/www/domain_2.com/docroot/test.php时,内容也显示在domain_1.com下。
我认为这是因为APC使用文件位置作为其缓存的密钥,在这两种情况下密钥都是/docroot/test.php。
清除操作码缓存可能仅限于单个池。我没有测试过这个。
编辑清除操作码缓存不会重新提交到单个应用程序池,调用apc_cache_clear()时会清除完整的APC缓存。
我还尝试使用apc.mmap_file_mask为每个池指定不同的掩码。这没有任何改变,一个应用程序池文件中的更新在其他池中可见。
使用apc.stat = 0设置时会观察到此行为。使用lsyncd监视对文件的所有更改,强制重新编译APC缓存中的条目。