3

Apologies of this has been asked before/elsewhere but I cannot find the answer.

We have some issues in the minute following a deploy and we think they are Opcache related. On our live setup we have the following Opcache settings:

opcache.revalidate_freq=60
opcache.validate_timestamps=1

Which of the following does PHP do?

  1. When PHP needs a file, does it at that point check if it has been 60 seconds since it last generated a new cache of the file and if it has been more then generate a new one for this request?

  2. Or does it run on some form of timer (or something else) where the 60 seconds is unrelated to when it last needed the file?

I'd expect option 1 but that wouldn't explain our 60 seconds or so of problems as the file path for the files is different as we deploy to an alternating A or B directory each time.

I hope that makes sense? Thanks for your help.

4

2 回答 2

4

根据我对 PHP 源代码的分析,会发生类似于选项 1 的情况。当 PHP 需要一个文件时,它会检查自上次编译或重新验证文件以来是否已经过了opcache.revalidate_freq几秒钟。如果不是,它会跳过重新验证(时间戳检查)。

换句话说,该opcache.revalidate_freq设置指定了时间戳检查的最大频率。文件在被请求之前不会被重新验证,即使距离上次重新验证已经过去一年。

资源

这是ZendAccelerator.c 中处理缓存验证的C 函数:

int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle)
{
    if (persistent_script->timestamp == 0) {
        return SUCCESS; /* Don't check timestamps of preloaded scripts */
    } else if (ZCG(accel_directives).revalidate_freq &&
        persistent_script->dynamic_members.revalidate >= ZCG(request_time)) {
        return SUCCESS;
    } else if (do_validate_timestamps(persistent_script, file_handle) == FAILURE) {
        return FAILURE;
    } else {
        persistent_script->dynamic_members.revalidate = ZCG(request_time) + ZCG(accel_directives).revalidate_freq;
        return SUCCESS;
    }
}

当一个脚本被成功重新验证时——也就是说,当 PHP 检查一个文件的时间戳并发现它自从文件被放入缓存后没有改变,它会在opcache.revalidate_freq几秒钟内将该文件标记为“新鲜”(.revalidate属性) . 这将防止在该时间段内进一步检查时间戳(PHP 将假定文件是新鲜的)。

如果重新验证不成功 - 即时间戳比缓存中的更新,这将导致重新编译,这也会设置相同的.revalidate属性(这在上面的代码中没有显示),再次免除文件在同一时期的重新验证.

上面的函数似乎只能从 调用persistent_compile_file(),这是一个在脚本执行时调用的函数。我找不到任何其他对它的引用,表明使用了另一个触发器,例如计时器。

于 2019-01-26T21:27:16.680 回答
1

所以,从PHP 手册

检查脚本时间戳以获取更新的频率,以秒为单位。0 将导致 OPcache 检查每个请求的更新。

所以发生的事情是你正在更新文件,但你的指令说从你更新文件到 opcache 构建一个新的操作码之间最多有 60 秒。

validate_timestamps有答案。因为你想手动重新验证文件,你可以这样做

当该指令被禁用时,您必须通过 opcache_reset()、opcache_invalidate() 或通过重新启动 Web 服务器手动重置 OPcache,以使对文件系统的更改生效。

于 2014-09-03T16:41:06.250 回答