如何清除 APC 缓存条目?

当我部署网站的新版本时,我需要清除所有 APC 缓存条目。 Php 有一个用于清除所有操作码缓存的按钮,但是我没有看到用于清除所有用户条目、所有系统条目或所有 Per-Directory 条目的按钮。

是否可以通过命令行或其他方式清除所有缓存条目?

217970 次浏览

可以使用 PHP 函数 apc_clear_cache

调用 apc_clear_cache()将清除系统缓存,调用 apc_clear_cache('user')将清除用户缓存。

文档中没有说明这一点,但要清除操作码缓存,您必须这样做:

apc_clear_cache('opcode');

编辑: 这似乎只适用于一些旧版本的 APC。

无论使用哪个版本,都不能从 php cli 脚本中清除 mod _ php 或 fastcgi APC 缓存,因为 cli 脚本将从 mod _ php 或 fastcgi 这样的不同进程中运行。必须从要清除缓存的进程(或子进程)中调用 apc _ clear _ cache ()。使用 curl 运行一个简单的 php 脚本就是这样一种方法。

我们遇到了 APC 和指向文件的符号链接的问题——它似乎忽略了文件本身的更改。不知何故,对文件本身执行触摸操作有所帮助。我不知道修改文件和触摸文件有什么区别,但不知怎么的,它是必要的..。

我不相信这些答案中的任何一个真的能够从命令行清除 APC 缓存。如上面的 法兰法马所述,CLI 运行在独立于 Apache 的进程中。

从命令行清除的解决方案是编写一个脚本,将 APC 清除脚本复制到 web目录并访问它,然后删除它。脚本仅限于从本地主机访问。

  1. Apc _ clear. php

    这是脚本复制到 web 目录、访问和删除的文件。

    <?php
    if (in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1')))
    {
    apc_clear_cache();
    apc_clear_cache('user');
    apc_clear_cache('opcode');
    echo json_encode(array('success' => true));
    }
    else
    {
    die('SUPER TOP SECRET');
    }
    
  2. Cache clearing script

    This script copies apc_clear.php to the web directory, accesses it, then deletes it. This is based off of a Symfony task. In the Symfony version, calls are made to the Symfony form of copy and unlink, which handle errors. You may want to add checks that they succeed.

    copy($apcPaths['data'], $apcPaths['web']); //'data' is a non web accessable directory
    
    
    $url = 'http://localhost/apc_clear.php'; //use domain name as necessary
    $result = json_decode(file_get_contents($url));
    
    
    if (isset($result['success']) && $result['success'])
    {
    //handle success
    }
    else
    {
    //handle failure
    }
    
    
    unlink($apcPaths['web']);
    

我知道这不适合每个人,但是: 为什么不做一个优雅的 Apache 重新启动?

例如,对于 Centos/RedHat Linux:

sudo service httpd graceful

Ubuntu:

sudo service apache2 graceful

创建 APC.php 文件

foreach(array('user','opcode','') as $v ){
apc_clear_cache($v);
}

在浏览器上运行。

对我来说,一个好的解决方案是在部署之后不再使用过时的用户缓存。

如果向每个键添加前缀,则可以在更改缓存条目的数据结构时更改前缀。这将帮助您在部署时获得以下行为:

  1. 在仅部署更新的结构之后,不要使用过时的缓存条目
  2. 不要在部署时清理整个缓存,以免降低页面的速度
  3. 一些旧的缓存条目可以在恢复部署之后重用(如果这些条目还没有被自动删除)
  4. APC 将在缺少缓存空间的 或者过期后删除旧的缓存条目

这只对用户缓存是可能的。

使用命令行的另一种可能性(尚未提及)是使用 curl。

如果您使用的是常用的 apc.php 脚本,那么这并不能解决所有缓存条目的问题,但是它可以调用一个经过改编的脚本或另一个已经安装的脚本。

这将清除操作码缓存:

curl --user apc:$PASSWORD "http://www.example.com/apc.php?CC=1&OB=1&`date +%s`"

将 OB 参数更改为3以清除用户缓存:

curl --user apc:$PASSWORD "http://www.example.com/apc.php?CC=1&OB=3&`date +%s`"

将两行都放在脚本中,并在 env 中使用 $PASSWORD 调用它。

如果您在 NGINX/PHP-FPM 堆栈上运行,那么最好的办法可能是重新加载 PHP-FPM

service php-fpm reload(或者任何你的重载命令可能在你的系统上)

APC 的稳定是有选择清除一个缓存在其接口本身。要清除这些条目,您必须登录到 apc 界面。

APC 可以选择在 APC.php 文件中设置用户名和密码。

enter image description here

如果您想清除命令式 apc 缓存: (如果需要,使用 sudo)

APCu

php -r "apcu_clear_cache();"

装甲运兵车

php -r "apc_clear_cache(); apc_clear_cache('user'); apc_clear_cache('opcode');"

Apc.ini

Stat = “1”将强制 APC 在每个请求上统计(检查)脚本,以确定脚本是否已被修改。如果它已经被修改,它将重新编译并缓存新版本。

如果这个设置是关闭的,APC 将不会检查,这通常意味着要强制 APC 重新检查文件,Web 服务器将不得不重新启动或缓存将不得不手动清除。请注意,FastCGI Web 服务器配置可能无法在重新启动时清除缓存。在脚本文件很少更改的生产服务器上,通过禁用统计信息可以获得显著的性能提升。

如果你在 ubuntu 下运行 fpm,需要运行下面的代码(在12和14上检查)

service php5-fpm reload

新的 APC 管理界面有添加/清除用户缓存和操作码缓存的选项,一个有趣的功能是添加/刷新/删除目录的 opCode 缓存

APC 管理文件

enter image description here

Apc _ clear _ cache ()只能在您希望清除缓存的同一 php SAPI 上工作。如果您有 PHP-FPM 并且希望清除 apc 缓存,那么必须通过一个 php 脚本来完成,而不是通过命令行,因为两个缓存是分开的。

我已经编写了 缓存工具,这是一个命令行工具,可以精确地解决这个问题,只需要一个命令,您就可以从命令行清除 PHP-FPM APC 缓存(它为您连接到 PHP-FPM,并执行 APC 函数)

它也适用于 opcache。

看看它是如何工作的: http://gordalina.github.io/cachetool/

按照 APC 文件的定义:

要清除缓存运行:

php -r 'function_exists("apc_clear_cache") ? apc_clear_cache() : null;'

如果你想通过 json 监视结果,你可以使用这样的脚本:

<?php


$result1 = apc_clear_cache();
$result2 = apc_clear_cache('user');
$result3 = apc_clear_cache('opcode');
$infos = apc_cache_info();
$infos['apc_clear_cache'] = $result1;
$infos["apc_clear_cache('user')"] = $result2;
$infos["apc_clear_cache('opcode')"] = $result3;
$infos["success"] = $result1 && $result2 && $result3;
header('Content-type: application/json');
echo json_encode($infos);

正如在其他答案中提到的,这个脚本将必须通过 http 或 curl 调用,如果它暴露在您的应用程序的 web 根目录中,您将必须保证安全。(由 ip,Token...)

我对 Symfony 构建的解决方案是在同一服务器上有大量实例:

第一步。 创建触发器或其他设置文件标志(例如 Symfony 命令) ,然后创建 marker file

file_put_contents('clearAPCU','yes sir i can buggy')

第二步。 在索引文件开始添加清除代码和删除 marker file

if(file_exists('clearAPCU')){
apcu_clear_cache();
unlink('clearAPCU');
}

第二步。 运行应用程序。

/storage/framework/cache/data/删除缓存文件

我启用了 APC,但是没有安装(也无法安装) ,所以它抛出了 Call to undefined function Illuminate\Cache\apc_store()

“好吧,我只要关闭它,它应该可以工作”。

没有,然后我被 Call to undefined function Illuminate\Cache\apc_delete()卡住了