15

互联网上有很多讨论,apc_cache_clear()在 CLI 中调用不会从“web”PHP 进程中清除操作码缓存,无论它们是在 Apache 内部运行还是由 FPM 运行(请参阅如何清除 APC 缓存条目?)。作为建议的解决方案,可以创建一个调用 的简单 PHP 页面apc_cache_clear(),然后从 CLI 调用它。Symfony 的 ApcBundle 就是这样做的。

如果apc_cache_clear()来自 CLI 没有清空 Apache/FPM 的缓存,是否在 FPM 工作人员之间?如果我通过 HTTP 调用 /clear_apc_cache.php,它只能由 FPM 工作进程之一运行。那么,APC 操作码缓存是否真的在池和工作人员之间共享 - 更具体地说:它是否会自动从所有工作人员中清除?

4

3 回答 3

25

所有的 php-fpm worker 共享与父 php-fpm 进程相同的操作码缓存;来源。如果你有一个 /apc_clear_cache.php 文件并通过 HTTP 调用它(使用 curl 之类的东西),你将使用相同的 php-fpm 主进程清除所有工作人员的操作码缓存。

这篇博客文章很好地解释了 apc 的工作原理以及如何在发布期间有效地清除它。

于 2012-10-19T20:16:50.573 回答
11

如果直接通过 FastCGI 接口执行脚本,则可以通过 cli 清除操作码缓存,而无需将文件部署到您的网站。

我创建了这个 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

于 2013-05-06T05:30:54.870 回答
3

我刚刚发现不同的池也共享相同的 APC 缓存,至少在带有 FPM 的 PHP 5.4 中以及就操作码缓存内容而言。

这就是我注意到它的方式:

我已经设置了多个 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 缓存中的条目。

  • 泰罗
于 2013-01-17T13:48:09.477 回答