【问题标题】:Why is my Symfony 2 cache warmer called multiple times?为什么我的 Symfony 2 缓存预热器被多次调用?
【发布时间】:2016-02-19 17:01:09
【问题描述】:

我在 Symfony 2 应用程序中的一个包有一个自定义缓存预热器。

当从控制台运行并在开发模式下,它会向标准输出写入一个通知,告知它已被调用。

有时,并非总是如此,它会为单个控制台缓存多次调用:clear 命令,这可以从多个通知写入标准输出中得到证明。

有人能解释一下为什么会这样吗?正常吗?是否所有缓存预热器都被多次调用?

环境:

  • Ubuntu 14.04.3
  • PHP 7.0.2-4
  • Symfony 2.7.9

----- 编辑 21-Feb-2016 08:36 --------

由于各种原因(大小、NDA 等),通过实际来源发布是不切实际的。所以,我创建了一个带有缓存预热器的小包,它在调用时只是回显其类名。

正如您在下面的输出中看到的,它被调用了两次。

//
// The cache warmer.
//
namespace SoBundle\Listener;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class CacheWarmer implements CacheWarmerInterface
{
    public function isOptional()
    {
        return false;
    }

    public function warmUp( $cacheDir )
    {
        echo __CLASS__ . '()' . PHP_EOL;
    }
}

#
# The service definition.
#
services:
    so.cache_warmer:
        class: SoBundle\Listener\CacheWarmer
        tags:
            - { name: kernel.cache_warmer }

#
# Clearing the cache...
#
$ console cache:clear
Clearing the cache for the dev environment with debug true
SoBundle\Listener\CacheWarmer()
SoBundle\Listener\CacheWarmer()

【问题讨论】:

  • 如果没有捆绑包自定义缓存预热器代码,无法帮助您...
  • 你到底为什么需要我更温暖的源代码。它实现了标准的东西:isOptional() 返回 false。 warmUp() 构建我的缓存。然后,当然还有服务定义,它指定类名、构造函数参数和 kernel.cache_warmer 作为名称标签的值。
  • 发布您的代码和您的尝试。它是您的自定义缓存加热器吗?它来自第 3 方捆绑包吗?您是否发现了任何特定情况下多次调用它而不是其他情况?如果您正在寻求帮助,请通过提供更多详细信息来帮助我们帮助您。
  • 好的。我已经发布了代码。
  • 几个月前我遇到了这个问题,并找到了对此行为的解释,但是......我不记得了。我会为您的问题添加书签,如果我记得它是什么,我会提供并回答:)。

标签: php symfony caching


【解决方案1】:

console cache:clear 的单次执行可触发缓存预热0 到 3 次,具体取决于以下因素:

  1. 缓存的当前状态,
  2. 可选参数(例如--no-warmup和--no-optional-warmers),
  3. 缓存预热器是否可选(根据isOptional() 方法)。

一个小介绍:Symfony 使用一个名为cache_warmer 的服务,它映射到Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate 类。它用于聚合所有已注册的带有kernel.cache_warmer 标记的缓存预热服务,并提供方便的执行方法。

有两种方法在console cache:clear 调用期间显式启动缓存预热:

  1. Symfony\Component\HttpKernel\Kernel::initializeContainer() - 在每次内核初始化时执行,无论是在控制台还是 web 模式下。如果您没有暖缓存,它会触发非可选的缓存暖器。
  2. Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand::warmup() - 由console cache:clear 命令执行。根据使用的选项,它会触发所有或仅可选的加热器。 但更重要的是,它实际上通过$this->getTempKernel() 创建了一个临时内核,它还会在初始化期间触发非可选的缓存预热器(如上所述)。

这会让您在 0-3 次调用之间调用每个缓存预热服务。基于 Symfony v2.8.3。

附:出于好奇,只用了 2 个小时来挖掘 Symfony 代码;)

【讨论】:

  • 这似乎有点低效,但由于缓存预热在每个生产版本中只发生一次,我想这是合理的。感谢您花时间挖掘它。我对 Symfony 内部结构的熟悉程度还不是很好。
猜你喜欢
  • 1970-01-01
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
  • 1970-01-01
相关资源
最近更新 更多