Skip to content

Кэш ответов ​

Кэширование целых HTTP-ответов. По умолчанию выключено, включается двумя настройками.

НастройкаПо умолчанию
pageblocks_http_cacheвыклВключает
pageblocks_http_cache_ttl3600Время жизни в секундах

Это не то же самое, что сервис Cache, который хранит значения, которые вы туда сами положили. Здесь хранятся отрендеренные страницы, и происходит это автоматически.

Что кэшируется ​

Только ответ, у которого выполняется всё три:

  • запрос GET,
  • от анонимного посетителя — не авторизован ни в текущем контексте, ни в mgr,
  • ответ 200.

Всё остальное проходит мимо: формы, менеджер, страница залогиненного пользователя, 404.

Почему только анонимные

Закэшированная страница общая для всех, кто попросит этот адрес. Один авторизованный ответ в таком хранилище — и следующий посетитель получит чужое приветствие. Правило узкое намеренно, и расширить его настройкой нельзя: цена ошибки — отдать данные одного пользователя другому.

Ключ ​

Ключ — это контекст, плюс хэш адреса запроса, плюс отпечаток гостевого состояния посетителя. Строка запроса входит в адрес, поэтому /catalog?page=2 и /catalog?page=3 — разные записи.

Отпечаток — это GuestCookies::fingerprint(), md5 от значений зарегистрированных гостевых cookie, пришедших с запросом. Отсюда три следствия:

  • у двух гостей ключи разные, и запись одного другому не достанется;
  • у одного и того же гостя ключ один, то есть кэш ему наконец работает;
  • у посетителя без гостевых cookie ключ прежний, байт в байт. Таких большинство — они делят одну запись, а не получают свою; заодно уже накопленный кэш после обновления остаётся годным.

Гостевая cookie должна быть зарегистрирована

В отпечаток попадают только имена, переданные в GuestCookies::register(). Незарегистрированная cookie с гостевым состоянием означает, что кэш не отличит одного гостя от другого — ровно та утечка, против которой всё и сделано. См. Гости.

Отпечаток считается один раз за запрос и запоминается. Ключ спрашивают дважды — на чтении в маршрутизации и на записи при отдаче ответа, — и токен, выданный между ними, иначе сохранил бы ответ под ключом, в который никто не смотрел.

Инвалидация происходит сама ​

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

Исключение — модель, которая объявила, что её сохранение не меняет ничего видимого посетителю: protected bool $flushesResponseCache = false; на ней отменяет сброс. Это про служебные таблицы — так отказался журнал почты: рассылка из трёхсот писем иначе чистила бы хранилище шестьсот раз подряд и превращала кэш в измеримое замедление. У всего, что хранит конструктор, значение по умолчанию — true.

Это намеренно грубо. Точная инвалидация — то место, где кэши ответов и ломаются: страницу, которая не обновилась, отлаживать заметно дороже, чем пережить повторное наполнение кэша. На сайте, где контент меняется пару раз в час, это ничего не стоит; на сайте, где что-то пишет в базу на каждом запросе, кэш не удержит ничего — и это признак, что фича такому сайту не подходит, а не повод усложнять правило.

Восстановление резервной копии тоже сбрасывает кэш.

Неудачный сброс проглатывается намеренно: проблема с кэшем не должна ломать сохранение модели или запрос.

Где это стоит ​

Поиск в кэше происходит в маршрутизации, до передачи запроса дальше: попадание стоит одного чтения и до контроллера не доходит. Запись — при отправке ответа и только для 200.

Записи живут в кэше MODX под pageblocks/http, поэтому очистка кэша сайта их убирает.

Когда включать ​

Имеет смысл для сайта, который в основном анонимно читают: каталог, блог, лендинг под нагрузкой. Магазин сюда тоже входит: гость с корзиной кэшируется под своим ключом, так что каталог отдаётся из хранилища, а корзина остаётся личной.

Бесполезно для личного кабинета и всего, где посетитель залогинен: такие запросы не кэшируются никогда, а проверка стоит немного на каждом.

Убедитесь, что он вообще работает

Включение ничего не меняет внешне, поэтому легко решить, что стало лучше. Измерьте: загрузите страницу гостем дважды и сравните время. Если вторая загрузка не быстрее, ничего не кэшируется — скорее всего, что-то пишет в базу на каждом запросе и тут же сбрасывает хранилище.

© PageBlocks 2019-present