Кеш в OpenCart на ревью: что проверить до продакшена
В OpenCart кеш способен ускорить каталог, а способен показать покупателю старую цену, остаток или валюту. На ревью важно проверить не только наличие кеша, но и ключи, инвалидирование, хранилище и поведение при нескольких серверах.

В OpenCart кеш часто добавляют как универсальное лекарство от медленного каталога, а на ревью находят другую проблему: карточка товара показывает старую цену, фильтр возвращает устаревший результат, а после деплоя часть страниц продолжает работать по старому коду. Ниже — разбор для OpenCart 3.x: какие слои кеширования нужно разделить, что проверять в коде и какие измерения снять перед изменениями.
Сначала разделите кеши OpenCart
Под словом «кеш» в проекте OpenCart обычно смешивают несколько разных механизмов. У них разные владельцы, срок жизни и способы очистки. Ревью, которое проверяет только вызов кеш-класса, пропускает большую часть рисков.
| Слой | Что хранит | Главный риск | Что проверить |
|---|---|---|---|
| Кеш приложения | Результаты запросов моделей, списки товаров, настройки и другие данные | Устаревшие значения или совпадение ключей | Ключ, срок жизни, очистку после изменения данных |
| Кеш модификаторов | Собранные изменения, применённые через OCMOD | Новый код не выполняется после установки расширения | Очистку и обновление кеша после изменения модификатора |
| Кеш шаблонов и темы | Скомпилированные представления и настройки оформления | Витрина не показывает внесённые изменения | Режим разработчика, очистку и различия окружений |
| PHP OPcache | Скомпилированный байткод PHP | Сервер продолжает исполнять старую версию файла | Политику сброса после деплоя и настройки перезапуска PHP |
| HTTP/CDN-кеш | Готовые ответы для браузера или прокси | Пользователь получает старую страницу независимо от OpenCart | Cache-Control, исключения для корзины и личного кабинета |
Эти слои нельзя очищать одной кнопкой и считать проблему решённой. Очистка кеша данных не обновляет OCMOD, а сброс OPcache не удаляет файл с результатом запроса.
На ревью кеш нужно оценивать не по вопросу «ускоряет ли он страницу», а по вопросу «какие данные он имеет право показывать устаревшими и кто отвечает за их обновление».
Кеш-ключ1 — идентификатор, по которому приложение сохраняет и достаёт результат. Если в ключе нет параметра, который влияет на ответ, два разных запроса могут получить один и тот же кеш.
Что проверить в коде
1. Состав кеш-ключа
Начните с места, где формируется ключ. Он должен учитывать все параметры, меняющие результат: идентификатор товара или категории, язык, валюту, customer group, магазин, страницу пагинации, сортировку и фильтры. Набор зависит от конкретного метода, поэтому универсальный шаблон ключа для всего OpenCart будет ошибкой.
Особенно опасен короткий ключ вроде имени метода или идентификатора категории. Один и тот же результат может быть корректным для гостя, но неверным для авторизованного покупателя с другой группой цен.
- Проверьте, что языковая метка входит в ключ для мультиязычных данных.
- Проверьте валюту и группу покупателя для цен, скидок и налогов.
- Проверьте магазин, если используется multistore.
- Проверьте порядок и нормализацию фильтров: одинаковый набор параметров не должен порождать несколько разных ключей.
- Проверьте пагинацию, лимит и сортировку для списков товаров.
Проверка считается пройденной, если два запроса, отличающиеся значимым параметром, не могут прочитать один и тот же результат только потому, что ключ сформирован слишком грубо.
2. Границы того, что можно кешировать
Кешировать справочник брендов или редко меняющиеся настройки проще, чем готовую страницу товара. Цена, остаток, доступность доставки и персональная скидка требуют более строгой политики. Если ответ зависит от сессии, корзины или учётной записи, кеширование целого HTML-ответа опаснее кеширования отдельного публичного блока.
На ревью найдите источник данных и задайте для него три вопроса: кто его меняет, как быстро изменение должно попасть на витрину и может ли ответ отличаться для двух пользователей. Если на третий вопрос ответ положительный, общий публичный кеш нужно ограничить или отказаться от него.
3. Срок жизни и инвалидирование
TTL — время жизни записи в кеше. Это не замена инвалидированию: если цена меняется раз в неделю, но ошибка в цене недопустима даже в течение минуты, одного большого TTL недостаточно.
Ищите место, где изменяются товар, цена, остаток, категория, настройка магазина или перевод. После такой операции должен обновляться затронутый кеш либо использоваться стратегия, которая гарантированно не отдаёт старое значение. Очистка всего кеша после каждого изменения проста, но под нагрузкой превращает обновление товара в массовый промах кеша.
Отдельно проверьте неуспешные операции. Если транзакция базы данных откатилась, кеш не должен содержать значение, которое не было сохранено. Если база обновилась, а очистка кеша завершилась ошибкой, система должна иметь понятный путь восстановления.
4. Хранилище и несколько серверов
Файловый кеш обычно прост для одного PHP-сервера, но становится спорным при нескольких узлах. Один сервер записал результат локально, другой его не видит. Общая файловая система решает доступ, но добавляет задержки, блокировки и отдельную точку отказа.
Внешнее хранилище снижает расхождение между узлами, но создаёт новую зависимость: сетевые ошибки, лимит памяти, вытеснение записей и права доступа. На ревью должен быть ответ, что произойдёт при недоступности кеша. Для каталога чаще безопаснее продолжить работу без кеша, чем показать неверную цену; для тяжёлого вычисления допустимы другие компромиссы. Это решение фиксируют отдельно для каждого участка.
Что измерить до и после изменений
Без замеров нельзя утверждать, что кеш ускорил OpenCart. Снимите показатели на одном и том же окружении: версия OpenCart 3.x, версия PHP, тип хранилища, объём каталога, включённые расширения и сценарий нагрузки.
- время ответа и p95 для главной страницы, категории, поиска и карточки товара;
- число SQL-запросов и время самых дорогих запросов;
- доля попаданий и промахов кеша, отдельно для каждого типа данных;
- размер кеша, число записей, частоту очисток и ошибки записи;
- поведение после изменения цены, остатка, языка и настроек магазина;
- разницу между первым запросом после очистки и повторным запросом.
Если в проекте нет счётчиков hit/miss, сначала добавьте наблюдаемость на уровне приложения или инфраструктуры. Не подменяйте её субъективным сравнением двух открытий страницы в браузере: результат зависит от браузерного кеша, CDN, сети и уже прогретого PHP.
Граничные случаи, которые ломают витрину
Цена, валюта и группа покупателя
Кеш цены без валюты и customer group в ключе — прямой риск коммерческой ошибки. То же касается налоговой настройки магазина и округления. Проверяйте не только обычного гостя, но и авторизованного пользователя с другой группой, другую валюту и товар со скидкой.
Остатки и параллельные заказы
Остаток может измениться между чтением из базы и показом страницы. Если проект показывает остатки почти в реальном времени, длинный TTL не соответствует бизнес-требованию. Проверьте сценарий двух параллельных заказов и момент, когда резерв или списание должно убрать старое значение с витрины.
Пагинация и фильтры
Список товаров легко закешировать неправильно: параметры фильтра передаются в URL, но ключ строится только по категории. Ещё одна ошибка — нестабильная сортировка, из-за которой товары переходят между страницами, а кеш продолжает отдавать старую разбивку.
Деплой и модификаторы
После изменения контроллера или шаблона результат может зависеть не только от файлов проекта, но и от кеша модификаций, шаблонов и OPcache. Процедура релиза должна явно описывать порядок обновления и очистки. Нажатие кнопки в административной панели не заменяет автоматизированный и проверяемый процесс деплоя.
Формулировки замечаний на ревью
Хорошее замечание указывает не на сам факт кеширования, а на воспроизводимый риск:
- «В ключе отсутствует язык, поэтому после первого запроса на русском английская версия может получить тот же результат».
- «Кешируется цена товара, но ключ не учитывает customer group и валюту».
- «После изменения остатка нет очистки записи; нужен тест на последовательность обновления товара и чтения карточки».
- «Файловое хранилище локальное, а приложение работает на нескольких узлах; опишите согласованность или ограничьте кеш одним узлом».
- «После очистки нет метрик промахов и времени восстановления; невозможно проверить, не превратил ли прогрев кеша релиз в пик нагрузки».
Требование «добавьте кеш» слишком расплывчато. Требование «ключ учитывает язык, валюту и группу покупателя, а изменение цены очищает связанные записи» можно проверить тестом и наблюдением в продакшене.
Что делать дальше
Составьте карту кешей проекта OpenCart 3.x: слой, ключ, источник данных, TTL, событие очистки, хранилище и поведение при ошибке. Затем добавьте тесты на цену, валюту, язык, остаток и фильтры. После выкладки смотрите не только p95, но и промахи кеша, ошибки хранилища и обращения пользователей с устаревшими данными. Инвалидация OCMOD и шаблонов — отдельная тема; здесь важно не смешивать её с кешем данных каталога.
1 Ключ кеша не обязан быть секретом. Это технический идентификатор записи, но в нём не должны оказаться персональные данные, токены или содержимое пользовательской сессии.
Логотип и фирменный стиль: Три концепции разного характера, палитра с обоснованием, проверка на читаемость в малом размере и в один цвет.
Спросить за 60 ₽Источники: OpenCart — официальный репозиторий, PHP Manual: OPcache
Частые вопросы
Для какой версии OpenCart подходит этот разбор?
Можно ли кешировать цену и остаток товара?
Почему после очистки кеша OpenCart сайт всё ещё показывает старый шаблон?
Что делать, если кеш работает на одном сервере, но ломается на нескольких?
Как понять, что кеш действительно ускоряет OpenCart?
Нужно ли очищать весь кеш после каждого изменения товара?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.