Перейти к содержимому

Кэш страниц для Odoo: магазин и блог из RAM или файла — быстро для посетителей, поисковых систем и ИИ

Модуль с открытым исходным кодом website_page_cache отдаёт публичные страницы Odoo практически как статические, поддерживает актуальность при изменениях и переводах и показывает в панели мониторинга, нужна ли RAM и сколько
10 ноября 2026 г. от
Кэш страниц для Odoo: магазин и блог из RAM или файла — быстро для посетителей, поисковых систем и ИИ

10 ноября 2026  |  Собственная разработка  |  Odoo, производительность и поисковые системы

Кэш страниц для веб-сайтов Odoo: публичные страницы магазина и блога из файла или RAM вместо повторного рендеринга при каждом обращении

Веб-сайт на Odoo заново формирует каждую страницу при каждом обращении: запросы к базе данных, шаблоны, переводы, цены. Для одного посетителя это незаметно. Но когда поисковые системы и ИИ-индексаторы запрашивают сотни или тысячи страниц на множестве языков, возникает постоянная нагрузка, и вместе с ними ждут настоящие клиенты. Для этого мы разработали модуль Odoo 19 website_page_cache и опубликовали его на GitHub как Open Source (LGPL-3): страницы магазина и блога, открываемые анонимно, отдаются практически как статические из кэша — либо из файлов, либо из оперативной памяти (RAM), а любое изменение – в том числе перевода – автоматически удаляет затронутые страницы из кэша.

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

Кратко

ТемаЧто действует
Модульwebsite_page_cache для Odoo 19, лицензия LGPL-3, публично на GitHub
Что кэшируется?Публичные страницы магазина и блога (списки, категории, товары, статьи) на каждом языке каждого веб-сайта
Для кого?Только для анонимных посетителей, только запросы GET без параметров поиска, только статус 200 с HTML
Место храненияФайлы на диске или RAM (tmpfs, общая для всех рабочих процессов); автоматически в зависимости от потребности в месте
АктуальностьКаждое изменение (в том числе переводы, импорты, скрипты) через триггеры базы данных создаёт запись в журнале и делает затронутые страницы недействительными
Панель мониторингаНастройки, состояние, статистика (попадания, промахи, сэкономленное время сервера) и проверка «Поместится ли в оперативную память?» включая «необходимый дополнительный объём RAM»
Поисковые системы и ИИНичего не блокируется и не ограничивается; все получают одни и те же страницы, только быстрее
Аварийный выключательОдин переключатель (enabled = 0) отключает кэш во всех рабочих процессах в течение 30 секунд

Проблема: нагрузка от краулеров на веб-сайты Odoo

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

Для поисковых систем и ИИ-индексаторов это постоянная проблема:

  • Много языков, много адресов: страница, существующая на 46 языках, для краулера — это 46 разных адресов.
  • Каждый адрес запрашивается отдельно, часто одновременно множеством распределённых отправителей. Обычный кэш браузера здесь не помогает, так как каждый запрос относится к новому адресу.
  • Мало рабочих процессов: служба Odoo обычно работает с горсткой процессов. Если они заняты запросами краулеров, настоящие посетители ждут в очереди.
  • Одно и то же содержимое снова и снова: статья блога меняется редко, но при каждом обращении её приходится затратно собирать заново.

Напрашивающийся выход – заблокировать краулеры – для компании, которая хочет быть найденной, не вариант. Видимость в поисковых системах и в ответах ИИ ценна. Лучше отдавать страницы так быстро, чтобы нагрузка почти не имела значения. Именно это и делает кэш страниц.

Как работает кэш страниц

Модуль встраивается во входную точку запросов Odoo (ir.http). При каждом обращении к странице он за доли миллисекунды решает, можно ли отдать её из кэша, и тогда отдаёт её без базы данных, без шаблона и без рендеринга.

Схема процесса: запрос, проверка, ключ кэша, попадание или промах, сохранение и отдача

  1. Проверка: рассматривается только анонимный запрос GET без параметров поиска по разрешённому пути (магазин, категории, товары, блог). Всё остальное обрабатывается Odoo как обычно.
  2. Ключ кэша: он состоит из веб-сайта, класса хоста, языка, пути, прайс-листа, налоговой позиции и статуса согласия на cookie. Поэтому посетители, которые увидели бы разное, никогда не делят одну запись. Хост при этом нормализуется: Odoo всегда формирует абсолютные адреса из домена веб-сайта, а не из запроса; адрес запроса лишь определяет, считается ли страница основным адресом (языковые ссылки) и должна ли она индексироваться. Поэтому все посторонние имена хостов делят одну запись вместе с указанием noindex, вместо того чтобы занимать отдельную копию каждое.
  3. Попадание: если есть актуальная запись, она отдаётся. CSRF-токен на странице при этом устанавливается заново для каждого запроса. Обращения к статьям блога по-прежнему учитываются.
  4. Промах: если записи нет или она устарела, Odoo формирует страницу как обычно. Если результат пригоден для кэширования (статус 200, HTML, без cookie, без идентификатора сессии в тексте), он сохраняется; следующее обращение будет попаданием.
  5. Видно в заголовке: каждый ответ содержит заголовок X-Page-Cache: HIT или MISS. Так любым инструментом можно проверить, что произошло.

Насколько быстрее?

В нашей тестовой системе (копия наших веб-сайтов, несколько сотен страниц) среднее время рендеринга страницы составляло около 490 миллисекунд, а отдача из кэша — около 23 миллисекунд: примерно в двадцать раз быстрее. Чем сложнее страница, тем больше выигрыш. По этим двум значениям панель мониторинга также вычисляет оценочную экономию времени сервера.

Файл или RAM: выбор места хранения

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

Сравнение файлового кэша и RAM-кэша и правило выбора в автоматическом режиме

НастройкаГде хранятся страницы?Свойства
ФайлыКаталог в папке данных Odoo, отдельный для каждой базы данныхсохраняется при перезапусках; часто используемые страницы операционная система и так держит в памяти
Оперативная памятьtmpfs в /dev/shmсамая быстрая отдача; теряется при перезапуске сервера и просто строится заново
АвтоматическиRAM, пока всё помещается; иначе файлыСлужебное задание (каждые 10 минут) принимает решение на основе оценки; при вердиктах «помещается» и «впритык» остаётся на RAM, чтобы выбор не менялся постоянно

Для большинства установок правильный выбор — Автоматически: вы получаете скорость RAM, когда места достаточно, и без вмешательства переходите на файлы, когда его не хватает.

Поместится ли веб-сайт в оперативную память? И сколько RAM не хватает?

Возможность RAM-кэша зависит от трёх факторов: от числа страниц, от их среднего размера и от доступной памяти. Панель мониторинга рассчитывает это для вас:

  • Число страниц: для каждого веб-сайта она подсчитывает опубликованные товары, страницы списков магазина, категории, статьи блога и списки блога и умножает на число языков.
  • Размер страницы: как только страницы попадают в кэш, измеряется фактическое среднее значение; до тех пор используется условное значение.
  • Место для кэша: наименьшее из заданного бюджета RAM, размера tmpfs и половины доступной оперативной памяти. Из-за кэша сервер никогда не должен испытывать нехватку памяти.
  • Вердикт: «помещается с запасом», «впритык», «слишком велик» или «RAM-кэш недоступен». «Помещается» означает, что потребность не превышает 80 процентов доступного места.

Раздел панели мониторинга «Поместится ли в оперативную память?» с числом страниц по веб-сайтам, потребностью в месте и указанием необходимой дополнительной RAM

Новое: сколько дополнительной RAM потребуется?

Если кэш не помещается, хочется знать, что нужно изменить. Поэтому под вердиктом панель мониторинга выводит конкретную строку: «Дополнительная RAM для RAM-кэша: примерно … больше оперативной памяти на этом сервере» – или «не требуется», если места уже достаточно. Если слишком мала не память сервера, а лишь одна из настроек, ниже указано, какая именно: бюджет RAM модуля или размер tmpfs (/dev/shm).

Панель мониторинга со слишком малым бюджетом RAM: вердикт «Нет» и призыв увеличить бюджет RAM как минимум до необходимого значения

Расчёт прост и прозрачен:

Пример расчёта: 12 000 страниц умножить на 25 КБ дают около 300 МБ потребности, с запасом около 375 МБ, для этого нужно не менее 750 МБ свободной памяти

  1. Потребность = страницы × средний размер страницы.
  2. С запасом = потребность, делённая на 0,8. Это значение должно умещаться в бюджет RAM и в tmpfs, чтобы вердикт был «помещается».
  3. Свободная память: поскольку кэш может использовать не более половины доступной оперативной памяти, серверу нужно как минимум вдвое больше значения из шага 2 в виде свободной памяти. Если чего-то не хватает, разница и есть необходимая дополнительная RAM.

Пример на изображении (12 000 страниц по 25 КБ) — это вспомогательный расчёт, а не измерение наших страниц. Для небольших веб-сайтов достаточно нескольких десятков мегабайт; тестовые данные на снимках экрана уложились примерно в 13 МБ.

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

Изменения и переводы очищают кэш

Кэш полезен только тогда, когда он никогда не отдаёт устаревшие страницы. Простое ограничение по времени («сбрасывать каждые двенадцать часов») было бы слишком грубым: изменённой цене или исправленной опечатке пришлось бы ждать до двенадцати часов. Поэтому модуль работает с учётом содержимого.

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

  1. Триггеры базы данных: на всех таблицах, которые могут влиять на страницу (товары, варианты, изображения, склад, атрибуты, категории, цены, налоги, прайс-листы, статьи блога и теги, данные партнёров и компаний, представления, ресурсы, меню, языки, настройки веб-сайта), установлены триггеры PostgreSQL. Они записывают каждое изменение в журнал изменений.
  2. Зависимости и состояние базы данных: каждая кэшированная страница запоминает, какие записи она показывает, и состояние базы данных, при котором она была создана.
  3. Сверка: если есть запись журнала, появившаяся после этого состояния и касающаяся одной из этих записей, страница устарела.
  4. Повторное кэширование: при следующем обращении устаревшая страница отбрасывается, формируется заново и снова сохраняется.

Переводы тоже учтены

Odoo 19 хранит переведённые тексты в той же записи, что и исходный текст (в виде поля JSON). Поэтому для базы данных изменение перевода — обычное изменение строки, и триггер его видит. Это в равной мере относится к редактированию через интерфейс, к импортам, интерфейсам и скриптам, пишущим напрямую в базу данных. Автоматический перевод на 46 языков делает недействительными именно те страницы, текст которых изменился, и не более того.

  • Точечно, а не огульно: изменение товара делает недействительными его страницы, списки, в которых он есть, и соответствующую категорию. Остальное остаётся в кэше.
  • Глобальные изменения (шаблоны, ресурсы, языки, меню, налоги, валюты) делают недействительным всё сразу, так как могут затрагивать любую страницу.
  • Счётчики не учитываются: счётчик просмотров статей блога меняется при каждом посещении; он сознательно не вызывает признания недействительности, иначе кэш был бы бесполезен для популярных статей.
  • Страховка: дополнительно существует максимальный возраст страницы (по умолчанию 12 часов).
  • Кэш не вызывает ошибок записи: ошибка внутри триггера записывается в журнал как предупреждение и не приводит к сбою самого сохранения.

Панель мониторинга и статистика

Всё необходимое для эксплуатации находится в одном месте: в Odoo в разделе Веб-сайт → Отчёты → Кэш страниц. Раздел Обзор — это панель мониторинга (с настройками), раздел История показывает цифры по дням и веб-сайтам.

Панель мониторинга кэша страниц в Odoo: настройки, состояние, статистика и проверка «Поместится ли в оперативную память»

Снимок экрана тестовой системы с копиями наших веб-сайтов; названия веб-сайтов заменены заполнителями.

Настройки

НастройкаЗначение
АктивноГлавный выключатель. Если выключен, Odoo снова отдаёт каждую страницу как раньше, во всех процессах не позднее чем через 30 секунд.
Место храненияАвтоматически, Файлы или Оперативная память
Максимальный возраст (часы)Страховка; страницы обновляются по истечении этого времени независимо от изменений
Бюджет RAM (МБ)Не более этого объёма оперативной памяти может занимать RAM-кэш; одновременно это граница для вердикта «помещается»
Предел диска (МБ)Максимальный размер файлового кэша; самые старые записи удаляются первыми

Состояние и статистика

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

Статистика (Сегодня, 7 дней, 30 дней) включает:

  • Из кэша и Сформировано: попадания и промахи, из них доля попаданий
  • Удалено (изменено/истекло): сколько страниц отброшено из-за изменения или истечения срока
  • Время рендеринга и время кэша: сравнение средних значений на страницу
  • Оценочная экономия времени сервера и объём данных из кэша

Цифры каждый рабочий процесс собирает самостоятельно и записывает раз в минуту; строки старше 90 дней служебное задание удаляет.

История в виде диаграммы, сводной таблицы и списка

В разделе История доступны суточные значения по каждому веб-сайту – в виде диаграммы, сводной таблицы или списка. Так видно, растёт ли доля попаданий после перезапуска или крупного изменения, и какой веб-сайт получает из кэша больше всего трафика.

История кэша страниц в виде сводной таблицы с попаданиями, промахами и отброшенными страницами по веб-сайтам

Безопасность: что никогда не берётся из кэша

Кэш страниц никогда не должен приводить к тому, что кто-то увидит чужое содержимое. Поэтому модуль следует принципу: при сомнении не кэшировать.

  • Только анонимные посетители: тот, кто вошёл в систему, имеет корзину или иное состояние сессии, всегда получает обычным образом сформированную страницу.
  • Только GET без параметров поиска: поиск, фильтры, сортировка, формы, корзина и оформление заказа остаются нетронутыми.
  • Только статус 200 и HTML: страницы ошибок, перенаправления и файлы не сохраняются.
  • Никаких идентификаторов сессии в кэше: страница, содержащая идентификатор сессии или устанавливающая cookie, не сохраняется (и фиксируется в журнале как предупреждение).
  • CSRF-токен для каждого запроса: токен в кэшированной странице — это заполнитель, который подставляется заново при каждой отдаче.
  • Тонкий ключ: веб-сайт, язык, прайс-лист, налоговая позиция и согласие на cookie входят в ключ кэша; кто видит иное, получает другую запись.
  • Несколько баз данных: у каждой базы данных свои записи, свой журнал и своя статистика.
  • Никакой утечки данных: кэш находится локально на сервере (файл или RAM). Никакие данные не передаются третьим лицам.

Поисковые системы и ИИ-индексаторы: ничего не блокируется

Некоторые операторы отвечают на нагрузку от краулеров блокировками. Это защищает сервер, но стоит видимости. Модуль выбирает противоположный путь:

  • Одинаковое содержимое для всех: поисковые системы, ИИ-индексаторы и посетители получают одну и ту же страницу. Нет отдельной «версии для краулеров» и нет распознавания по идентификатору браузера.
  • Более быстрые ответы помогают индексации: страница, отвечающая за 20, а не за 500 миллисекунд, меньше расходует краулинговый бюджет, и краулеры успевают охватить больше страниц за то же время.
  • Актуальное содержимое: поскольку изменения немедленно делают страницы недействительными, краулеры никогда не видят устаревшую версию – это важно, если вы ведёте содержимое для поиска и ответов ИИ.
  • Структурированные данные сохраняются: JSON-LD, метаданные и ссылки hreflang являются частью кэшированной страницы; карты сайта и файлы кэш не затрагивает.

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

Минификация HTML и отдача в сжатом виде

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

  • Минификация (параметр website_page_cache.minify): HTML-комментарии удаляются, пробельные символы объединяются. Полностью они удаляются только там, где браузер их всё равно игнорирует, например между блочными элементами. Промежутки между строчными элементами сохраняются, pre, textarea и скрипты остаются без изменений, структурированные данные (JSON-LD) переписываются в компактном виде. В зависимости от страницы страницы становятся на 10–30 % меньше. При тесте с семью реальными страницами текст, число элементов, положение всех элементов и снимок экрана совпали с оригиналом. Первая отдача (MISS) минифицирована так же, как и все последующие (HIT).
  • Сжатие (параметр website_page_cache.compress): страницы из кэша отдаются через gzip (Content-Encoding: gzip, Vary: Accept-Encoding). Большие пакеты ресурсов (CSS и JavaScript, до нескольких МБ) Odoo сам отдаёт без сжатия; модуль сжимает их один раз, сохраняет копию на диске и затем отдаёт её напрямую. Так из 2,1 МБ CSS получилось 0,27 МБ, из 4,8 МБ JavaScript — 1,1 МБ. Старые копии удаляет служебное задание.
  • После перезагрузки компьютера: RAM-кэш сохраняется при перезапусках Odoo, но не при перезагрузке сервера. Поэтому служебное задание постепенно зеркалирует его на диск (параметр website_page_cache.persist) и восстанавливает при запуске. Действительна ли восстановленная запись, проверяет тот же механизм, что и обычно: возраст и журнал изменений. Минификация при этом заново не вычисляется.

Установка и настройки

  1. Получить модуль: скачайте исходный код с GitHub и поместите его в путь addons вашей установки Odoo 19: github.com/Alex0176/odoo-website-page-cache
  2. Установить: odoo-bin -d <Datenbank> -i website_page_cache --stop-after-init. При этом создаются журнал изменений, триггеры и служебное задание (каждые 10 минут).
  3. Перезапустить службу, чтобы все рабочие процессы загрузили модуль.
  4. Открыть панель мониторинга: Веб-сайт → Отчёты → Кэш страниц. Проверьте, полно ли отслеживание изменений, и выберите место хранения (по умолчанию: автоматически).
  5. Проверить: дважды запросите страницу магазина или блога и посмотрите заголовок X-Page-Cache: в первый раз MISS, затем HIT.

Настройки хранятся как системные параметры (website_page_cache.enabled, .backend, .ttl_hours, .max_mb_file, .max_mb_ram) и обычно ведутся в панели мониторинга. Модуль переведён на немецкий язык. Удаление полностью убирает триггеры, журнал и все кэшированные страницы.

Совет для RAM-кэша: бюджет RAM в панели мониторинга и размер tmpfs (/dev/shm, параметр монтирования size=) должны соответствовать потребности. Оба значения называет вам проверка «Поместится ли в оперативную память?» с конкретными цифрами.

Ограничения, о которых следует знать

  • Небольшая задержка после изменений: индекс журнала изменений обновляется каждые две секунды. До этого момента изменённая страница может ещё отдаваться в старой версии.
  • Тексты, зависящие от склада, обновляются через изменения запасов и максимальный возраст.
  • Оценка потребности в месте: дополнительные версии для каждого прайс-листа или страны не учитываются; заложите небольшой запас.
  • Не замена всему: кэш разгружает запросы, которые ему разрешено обслуживать. Вошедшие в систему пользователи, поиск и формы по-прежнему проходят через Odoo.
  • Первое обращение остаётся медленным: после перезапуска сервера (RAM) или глобального изменения каждая страница один раз формируется обычным образом, прежде чем попасть в кэш.

Частые вопросы

Что такое кэш страниц для Odoo?

Модуль с открытым исходным кодом (website_page_cache, Odoo 19, LGPL-3), который отдаёт публичные страницы магазина и блога анонимным посетителям из кэша, вместо того чтобы формировать их заново при каждом обращении. Кэш размещается по выбору в файлах или в оперативной памяти.

Блокирует ли модуль поисковые системы или ИИ-краулеры?

Нет. Поисковые системы и ИИ-индексаторы получают те же страницы, что и любой другой посетитель, только быстрее. Нет ни блокировки, ни ограничения скорости, ни отдельной версии для краулеров.

Кэшируются ли изменённые страницы и переводы заново автоматически?

Да. Триггеры PostgreSQL сообщают о каждом изменении соответствующих таблиц в журнал; затронутые страницы отбрасываются и при следующем обращении формируются заново и сохраняются. Переводы учтены, потому что Odoo 19 хранит их в той же записи.

Что выбрать: файл или RAM?

Как правило, Автоматически: модуль использует RAM, пока все страницы в неё помещаются, и иначе переходит на файлы. Файлы подходят, если кэш должен пережить перезапуски или RAM мало; RAM — самый быстрый вариант.

Как узнать, поместится ли мой веб-сайт в оперативную память?

В панели мониторинга в разделе Веб-сайт → Отчёты → Кэш страниц. Раздел «Поместится ли в оперативную память?» подсчитывает страницы по веб-сайтам и языкам, измеряет размер страницы и сравнивает потребность с бюджетом RAM, размером tmpfs и доступной памятью.

Сколько дополнительной RAM нужно для RAM-кэша?

Панель мониторинга показывает это отдельной строкой. Расчёт: потребность = страницы × размер страницы; с запасом надёжности делится на 0,8. Поскольку кэш может использовать не более половины доступной памяти, вдвое большее значение — это необходимая свободная память; разница — дополнительная RAM. Если слишком мал только бюджет RAM или tmpfs, панель мониторинга называет настройку вместе с целевым значением.

Может ли кэш показать кому-то чужое содержимое?

Нет. Кэшируются только анонимные запросы GET без параметров поиска. Вошедшие в систему пользователи, корзины, формы и поиск никогда не берутся из кэша; язык, прайс-лист, налоговая позиция и согласие на cookie входят в ключ.

Как отключить кэш в экстренном случае?

В панели мониторинга выключите переключатель «Активно» или установите системный параметр website_page_cache.enabled в значение 0. Это действует во всех рабочих процессах не позднее чем через 30 секунд. Удаление модуля дополнительно убирает триггеры, журнал и кэшированные страницы.

Как понять, что страница пришла из кэша?

По заголовку ответа X-Page-Cache: HIT означает из кэша, MISS означает только что сформирована и сохранена.

Уменьшает ли модуль HTML и сжимает ли его?

Да. Кэшированные страницы минифицируются консервативно (комментарии и лишние пробельные символы удаляются, содержимое и отображение остаются прежними) и при попаданиях в кэш отдаются через gzip; пакеты ресурсов сжимаются один раз и отдаются с диска. И то и другое можно отключить параметрами website_page_cache.minify и website_page_cache.compress.

Поддержка от Biricon IT Services

Ваш веб-сайт на Odoo медленно реагирует при нагрузке от краулеров, или вы хотите сделать магазин и блог быстрее и заметнее? Мы поможем с анализом нагрузки, с настройкой кэша страниц, с расчётом оперативной памяти и рабочих процессов и с многоязычной поисковой оптимизацией вашего веб-сайта на Odoo. Исходный код модуля вы найдёте на GitHub.

Связаться с нами

По состоянию на 10 ноября 2026. Измеренные значения получены в тестовой системе на примерных данных и не являются гарантией для других установок.