Как переопределить операции plone.app.caching для использования Apache mod_cache с Plone

Мы используем Plone 4.1 с plone.app.caching за Apache 2.2 с mod_cache и mod_disk_cache.

Предопределенные операции, доступные с plone.app.caching, не совсем подходят для этой конфигурации, поскольку Apache не будет кэшировать ответы, если max-age=0, независимо от того, какие значения вы установили для Expires и s-max- возраст (я думаю, что это противоречит спецификации HTTP 1.1). В Plone 3.3 и CacheFu это было простым изменением конфигурации, чтобы обойти это: установить max-age=1 для соответствующего набора заголовков. См. эту проблему с CacheFu

Я ищу совет, как добиться того же с помощью plone.app.caching. Каков самый простой способ переопределить операцию plone.app.caching.moderateCaching, чтобы для ее maxage было установлено значение 1, а не 0?

В данный момент мы не рассматриваем возможность добавления Squid или Varnish в наш стек.


person scarba05    schedule 06.07.2011    source источник


Ответы (5)


То, что вы запрашиваете, на самом деле является strongCaching (но с коротким сроком действия), поэтому используйте его вместо этого. По определению, модерация кэширования предназначена для «кэширования в браузере с немедленным истечением срока действия» — другими словами, max-age=0.

Три операции кэширования по умолчанию — strongCaching, умеренныйCaching и weakCaching — это всего лишь полезные абстракции, предназначенные для облегчения понимания выбора, связанного с назначением политик кэширования. Если абстракции вам не помогают, вы можете делать почти все, что вам нужно, просто используя strongCaching и изменяя настройки.

Более подробно это обсуждается в документации plone.app.caching, http://pypi.python.org/pypi/plone.app.caching

person newbery    schedule 27.07.2011
comment
Сильное кэширование с коротким сроком действия здесь не подойдет. Как только вы установите ненулевое значение max-age plone.app.caching.operations.utils.cacheInBrowserAndProxy, принудительно будет использоваться общедоступный заголовок управления кешем. Что мне действительно нужно, чтобы иметь возможность переопределить cacheInBrowserAndProxy и cacheInProxy с логикой, согласно которой, если s-maxage не равен нулю, а maxage равен нулю, тогда установите maxage в 1 - person scarba05; 08.09.2011
comment
Возможно, я что-то не понимаю, но это не имеет смысла для меня. Практически по определению все, что имеет ненулевое значение maxage, является общедоступным. В любом случае, общедоступный токен — это просто подсказка для эвристики кэширования — я сомневаюсь, что это изменит поведение кэшей, когда они увидят maxage=1. - person newbery; 09.09.2011
comment
Я пытался понять, почему вас беспокоит публичный токен. Вас беспокоит кеширование страниц авторизованных пользователей? Уже существует механизм для сохранения конфиденциальности аутентифицированных страниц — просто добавьте соответствующий тег etag («userid» или «roles»), чтобы вызвать приватный ответ для вошедших в систему пользователей. Обратите внимание: прежде чем пытаться кэшировать страницы с таким раздвоением личности, обязательно прочтите раздел документации plone.app.caching о кэшировании с раздвоением представления. - person newbery; 09.09.2011
comment
Причина в том, чтобы обойти эту ошибку Apache issues.apache.org/bugzilla/ show_bug.cgi?id=35247 - person scarba05; 09.09.2011
comment
Нет. Эта ошибка является причиной вашей первоначальной проблемы, но это НЕ причина для беспокойства по поводу общедоступного токена, выданного plone.app.caching. Опять же, ради всех, кто следит за этой темой, вы можете получить практически любую разумную коллекцию заголовков кеша только с помощью операции strongCaching и некоторых подходящих настроек. - person newbery; 10.09.2011
comment
Согласитесь, что положительный max-age подразумевает public. Чего мне нужно добиться, так это, по сути, заставить apache кэшировать объект, если заголовки подразумевают, что прокси-серверы должны кэшироваться. т. е. если max-age=0 и s-maxage›0, тогда установите max-age равным 1. - person scarba05; 13.09.2011

Вот и вся настраиваемая политика. Вы можете установить его в панели управления или (как я предпочитаю) в общем реестре установки.xml. См. примеры политик в plone.app.caching.

Обновление:

Панель управления пытается упростить ситуацию, ограничивая то, что установлено в политиках кэширования по умолчанию. Однако их по-прежнему можно изменить непосредственно в реестре, поэтому вы можете использовать следующее в файле реестра.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>
person Laurence Rowe    schedule 06.07.2011
comment
Для plone.app.caching.moderateCaching maxage жестко запрограммирован на 0. maxage не включен в plone.app.caching.operations.default.ModerateCaching.options, поэтому у вас нет возможности установить его в панели управления и попытаться установить его. использование реестра.xml ничего не делает. - person scarba05; 06.07.2011
comment
Лоуренс. Спасибо за вашу помощь здесь, но довольно необычно я не думаю, что вы правы в этом случае. Я не могу заставить конфигурацию, которую вы предоставляете, работать. Проверка plone.caching.utils.lookupOptions показала, что из реестра загружаются только параметры, определенные в атрибуте options типа операции. - person scarba05; 07.07.2011
comment
Да, похоже, ты прав. Я действительно не вижу причин для этого или почему это скрыто в этом типе. Возможно, стоит зарегистрировать ошибку. - person Laurence Rowe; 07.07.2011
comment
Нет, это не ошибка. Подробности смотрите в моем ответе. - person newbery; 27.07.2011

Лоуренс нашел для меня соответствующую ошибку Apache https://issues.apache.org/bugzilla/show_bug.cgi?id=35247

Поскольку мы собираем Apache сами, мы решили вместо этого пропатчить Apache и оставить Plone в покое, хотя патч предназначен для магистрали, и поэтому применить его к коду 2.2 немного сложно.

person scarba05    schedule 09.09.2011

После долгих размышлений мы решили эту проблему с помощью некоторой конфигурации Apache. Мы изменили заголовки ответа, чтобы установить max-age равным 1, если max-age = 0 и s-maxage положителен, а затем удалили заголовок expires:

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

Это делает свое дело, хотя клиенты HTTP 1.0 теперь не будут знать, что у них есть Expires, на которых они основывают свое кэширование.

person scarba05    schedule 13.09.2011

Я предполагаю, что реальный ответ здесь, вероятно, заключается в том, что на данный момент нет простого способа сделать это. Я поднял ошибку Plone, позволяющую переопределить max-age с умеренным кэшированием

Итак, вот мое решение, которое работает, но кажется много работы по сравнению с возможностью переопределить максимальный возраст по умолчанию при умеренном кэшировании. Я определяю свою собственную операцию кэширования, которая расширяет 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" />

Затем в моем универсальном профиле установки register.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>          

Вы также можете определить некоторые переопределения для конкретных типов.

Если кто-то может предложить более простой способ добиться этого, пожалуйста, дайте мне знать

person scarba05    schedule 06.07.2011
comment
Это намного сложнее, чем необходимо. Просто используйте strongCaching и установите max-age на то, что вам нравится. Подробности смотрите в моем ответе. - person newbery; 28.07.2011
comment
На самом деле это не работает для вошедших в систему пользователей, поскольку cacheInBrowserAndProxy принудительно использует общедоступный заголовок управления кешем. - person scarba05; 08.09.2011
comment
Как и должно быть. Все, что имеет ненулевой maxage, по определению общедоступно. - person newbery; 09.09.2011