【问题标题】:How to override plone.app.caching operations for using Apache mod_cache with Plone如何覆盖 plone.app.caching 操作以将 Apache mod_cache 与 Plone 一起使用
【发布时间】:2011-07-06 10:56:25
【问题描述】:

我们在 Apache 2.2 之后运行带有 plone.app.caching 的 Plone 4.1,带有 mod_cache 和 mod_disk_cache。

plone.app.caching 提供的预定义操作不太适合此配置,因为如果 max-age=0,Apache 不会缓存响应,无论您为 Expires 和 s 设置了什么值-max-age(我认为这与 HTTP 1.1 规范相反)。使用 Plone 3.3 和 CacheFu,可以通过直接的配置更改来解决这个问题:为相关标头集设置 max-age=1。看到这个CacheFu issue

我正在寻找一些建议来实现与 plone.app.caching 相同的目标。覆盖 plone.app.caching.moderateCaching 操作以使其 maxage 设置为 1 而不是 0 的最简单方法是什么?

我们目前不考虑将 Squid 或 Varnish 添加到我们的堆栈中。

【问题讨论】:

    标签: apache caching plone


    【解决方案1】:

    您要求的实际上是 strongCaching(但过期时间很短),因此请改用它。根据定义,moderateCaching 旨在“缓存在浏览器中但立即过期”——换句话说,max-age=0。

    三种默认缓存操作——strongCaching、moderateCaching 和weakCaching——只是有用的抽象,旨在使分配缓存策略所涉及的选择更易于理解。如果抽象对您没有帮助,您几乎可以通过使用 strongCaching 并更改设置来完成您需要的任何事情。

    这在 plone.app.caching 文档http://pypi.python.org/pypi/plone.app.caching中有更详细的讨论

    【讨论】:

    • 强缓存和短暂的过期在这里是不行的。只要您设置了非零 max-age plone.app.caching.operations.utils.cacheInBrowserAndProxy 就会强制使用“公共”缓存控制标头。我真正需要能够覆盖的是cacheInBrowserAndProxycacheInProxy,如果 s-maxage 不为零且 maxage 为零,则将 maxage 设置为 1
    • 也许我误解了一些东西,但这对我来说没有意义。几乎按照定义,任何设置为非零最大值的东西都是公开的。无论如何,公共令牌只是缓存启发式的提示——我怀疑它会改变缓存在看到 maxage=1 时的行为方式。
    • 我试图弄清楚您为什么担心“公共”令牌。您是否担心缓存来自登录用户的页面?已经有一种机制可以使经过身份验证的页面保持私密——只需添加适当的 etag('userid' 或 'roles')来触发登录用户的私密响应。请注意,在您开始尝试缓存具有这种拆分特性的页面之前,请确保您阅读了 plone.app.caching 文档中有关拆分视图缓存的部分。
    • 原因是为了绕过这个 Apache 错误issues.apache.org/bugzilla/show_bug.cgi?id=35247
    • 没有。该错误是您最初问题的原因,但不是担心 plone.app.caching 发布的“公共”令牌的理由。同样,为了关注此线程的其他人,您可以通过 strongCaching 操作和一些合适的设置获得几乎任何合理的缓存头集合。
    【解决方案2】:

    这就是所有可配置的策略。您可以在控制面板中进行设置,或者(如我所愿)在通用设置 registry.xml 中进行设置。请参阅 plone.app.caching 中的示例策略。

    更新:

    控制面板试图通过限制默认缓存策略上的设置来简化事情。不过,仍然可以直接在注册表中更改这些内容,因此您可以在 registry.xml 中使用以下内容:

    <record name="plone.app.caching.moderateCaching.maxage">
        <field type="plone.registry.field.Int">
            <title>Maximum age</title>
            <description>Time (in seconds) to cache the response in the browser or caching proxy</description>
            <required>False</required>
        </field>
        <value>1</value>
    </record>
    

    【讨论】:

    • 对于 plone.app.caching.moderateCaching,maxage 被硬编码为 0。maxage 不包含在 plone.app.caching.operations.default.ModerateCaching.options 中,因此您无法设置它控制面板并尝试使用 registry.xml 设置它什么都不做。
    • 劳伦斯。感谢您在这里的帮助,但在这种情况下,我不认为您是对的。我无法让您提供的配置正常工作。检查 plone.caching.utils.lookupOptions 似乎只有在操作类型的选项属性中定义的选项才能从注册表中加载。
    • 是的,看起来你是对的。我真的没有看到任何原因,或者为什么它隐藏在那种类型上。也许值得提交一个错误。
    • 不,这不是错误。详情见我的回答。
    【解决方案3】:

    Laurence 为我找到了相关的 Apache 错误 https://issues.apache.org/bugzilla/show_bug.cgi?id=35247

    当我们自己构建 Apache 时,我们决定给 Apache 打补丁,而不要管 Plone,尽管该补丁是针对主干的,因此应用于 2.2 代码有点棘手。

    【讨论】:

      【解决方案4】:

      经过深思熟虑,我们通过一些 Apache 配置解决了这个问题。我们修改了响应头,如果 max-age = 0 并且 s-maxage 为正,则将 max-age 设置为 1,然后删除 expires 头:

      Header edit Cache-Control max-age=0(.*s-maxage=[1-9].*) max-age=1$1
      Header unset Expires
      

      尽管 HTTP 1.0 客户端现在不知道是否有 Expires 来作为缓存的基础,但这样做可以解决问题。

      【讨论】:

        【解决方案5】:

        我想这里的真正答案可能是目前没有简单的方法可以做到这一点。我提出了Plone bug to allow max-age to be overriden with moderateCaching

        所以这是我的解决方案,它有效,但与能够覆盖适度缓存的默认最大年龄相比,似乎需要做很多工作。我定义了自己的缓存操作,它扩展了 plone.app.caching.operations.default.moderateCaching:

        class CacheInApache(ModerateCaching):
            """ Apache won't cache a response if max-age cache control is 0.  Override ModerateCaching
                and set it to 1 second.
            """
            classProvides(ICachingOperationType)
        
            title = _(u"Cache in Apache")
            description = _(u"Moderate caching for Plone behind Apache. max-age set to 1")
            prefix = 'cacheInApache'
        
            maxage = 1  
        

        在configure.zcml中注册

        <adapter factory=".operation.CacheInApache" 
                name="cacheInApache" />
        <utility component=".operation.CacheInApache" 
                name="cacheInApache" />
        

        然后在我的通用设置配置文件 registry.xml 中配置我的类型以使用它并定义其字段。

        <record name="plone.caching.interfaces.ICacheSettings.operationMapping">
            <value purge="False">
                <element key="plone.resource">plone.app.caching.strongCaching</element>
                <element key="plone.stableResource">plone.app.caching.strongCaching</element>
                <element key="plone.content.itemView">cacheInApache</element>
                <element key="plone.content.feed">cacheInApache</element>
                <element key="plone.content.folderView">cacheInApache</element>
                <element key="plone.content.file">cacheInApache</element>
            </value>
        </record>
        <record name="cacheInApache.smaxage">
            <field type="plone.registry.field.Int">
                <title>Shared maximum age</title>
                <description>Time (in seconds) to cache the response in the caching proxy</description>
                <required>False</required>
            </field>
            <value>86400</value>
        </record>
        <record name="cacheInApache.etags">
            <field type="plone.registry.field.Tuple">
                <title>ETags</title>
                <description>A list of ETag component names to include</description>
                <value_type type="plone.registry.field.ASCIILine" />
                <required>False</required>
            </field>
            <value>
            </value>
        </record>
        <record name="cacheInApache.lastModified">
            <field type="plone.registry.field.Bool">
                <title>Last-modified validation</title>
                <description>Turn on Last-Modified headers</description>
                <required>False</required>
            </field>
            <value>False</value>
        </record>
        <record name="cacheInApache.ramCache">
            <field type="plone.registry.field.Bool">
                <title>RAM cache</title>
                <description>Turn on caching in Zope memory</description>
                <required>False</required>
            </field>
            <value>False</value>
        </record>
        <record name="cacheInApache.vary">
            <field type="plone.registry.field.ASCIILine">
                <title>Vary</title>
                <description>Name(s) of HTTP headers that must match for the caching proxy to return a cached response</description>
                <required>False</required>
            </field>
            <value></value>
        </record>
        <record name="cacheInApache.anonOnly">
            <field type="plone.registry.field.Bool">
                <title>Only cache for anonymous users</title>
                <description>Ensure logging users always get a fresh page. Note that if you are caching pages in a proxy cache, you'll still need to use a Vary response header to keep anonymous and authenticated content separate.</description>
                <required>False</required>
            </field>
            <value>False</value>
        </record>          
        

        您还可以定义一些特定类型的覆盖。

        如果有人可以提出更简单的方法来实现这一点,请告诉我

        【讨论】:

        • 这比必要的要复杂得多。只需使用 strongCaching 并将 max-age 设置为您喜欢的任何内容。详情见我的回答。
        • 实际上这对登录用户不起作用,因为cacheInBrowserAndProxy 强制使用公共缓存控制标头。
        • 应该如此。根据定义,任何具有非零最大值的东西都是公共的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-16
        • 2015-08-24
        • 1970-01-01
        • 2011-07-18
        • 1970-01-01
        相关资源
        最近更新 更多