Кеш GLPI: почему ваше изменение не появляется на экране

GLPI хранит три разных кеша, а кнопки очистки появляются только в режиме отладки. Разбираем, какой кеш очищать при каждом симптоме, в GLPI 10, 11 и 12.

В этой статьеРазделов: 13

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

В GLPI не «один кеш». Их три.

Это первое, что обычно вызывает путаницу. Когда кто-то говорит «очисти кеш GLPI», за этим стоят три разные вещи с разным назначением, и очистка не того кеша ничего не решает:

  • Кеш опкодов (PHP): хранит байт-код уже скомпилированных файлов .php, чтобы PHP не интерпретировал код заново при каждом запросе. Это расширение Zend OPcache самого PHP, а не GLPI.
  • Кеш пользовательских данных: хранит данные приложения, например настройки и списки, к которым GLPI обращается постоянно. Внутри GLPI этот контекст называется core, и он может находиться на диске или в Redis/Memcached.
  • Кеш переводов: хранит уже обработанные языковые каталоги, чтобы GLPI не читал файлы .mo на каждом экране. Именно он отвечает за самый частый симптом: текст, который остаётся на старом языке.

Практическое правило: если изменился код, подозреваемый — кеш опкодов. Если изменился текст интерфейса — кеш переводов. Если изменились настройки или данные — кеш пользовательских данных.

Где находятся эти файлы

Дисковый кеш GLPI живёт внутри папки файлов инсталляции, в files/_cache/. Внутри есть каталог с именем примерно такого вида:

files/_cache/11.0.7-49a93008-production/
    app/
    templates/
    translations/

Предупреждение об этих трёх папках: они не соответствуют один к одному трём кешам на экране. Папка translations действительно хранит языковые каталоги, но app — это внутренний кеш фреймворка (контейнер внедрения зависимостей, аннотации), а не кеш пользовательских данных. А если среда настроена на Redis или Memcached, пользовательских данных в этом каталоге нет вовсе: они живут во внешнем сервисе, а папка на диске продолжает существовать с кешем фреймворка. Искать там в этом случае — значит искать не в том месте.

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

Внимание, если вы на GLPI 10: такая организация в одном версионированном каталоге характерна для линеек 11 и 12, работающих на Kernel Symfony. В GLPI 10 тот же files/_cache устроен иначе: отдельные папки и без суффикса среды:

files/_cache/core/
files/_cache/templates/
files/_cache/installer-10.0.24/
files/_cache/translations-10.0.24/

Обратите внимание, что там версию в имени несут только установщик и переводы, а старые версии накапливаются: часто можно найти полдюжины translations-10.0.x от прошлых обновлений. Пути меняются, но логика статьи та же, а кнопки интерфейса и консольная команда работают одинаково.

Плагины тоже используют этот каталог. В инсталляции с NexTool, например, там соседствуют такие файлы, как nextool_boot_manifest.cache, и записи по модулям, у каждого из которых своя стратегия инвалидации.

Диск или Redis: где находится ваш кеш

Кеш пользовательских данных и кеш переводов не обязательно находятся на диске. GLPI позволяет направить их в Redis или Memcached, и сам экран «Производительность» сообщает, какая система используется, например «Расширение кеша redis установлено» или «Используется система кеширования filesystem».

Это меняет диагностику в двух распространённых сценариях. В инсталляции с несколькими серверами приложений за балансировщиком дисковый кеш означает отдельный кеш на каждом сервере: очистка на одном узле не очищает остальные, и пользователь видит старое или новое содержимое в зависимости от того, куда попал запрос. С общим Redis одна очистка действует для всех.

Другой сценарий — контейнер. Если кеш лежит на диске внутри контейнера, а не в томе, пересоздание контейнера очищает и кеш, что иногда «решает» проблему случайно и скрывает настоящую причину.

Чтобы проверить или изменить настройку из командной строки:

php bin/console cache:configure

У плагинов тоже есть кеш

Помимо трёх кешей ядра, каждый плагин может вести свой. GLPI предоставляет отдельный контекст для каждого плагина, и именно поэтому команда очистки принимает --context=plugin:nome_do_plugin.

Стоит оговориться: этот контекст существует, только если плагин использует API кеширования самого GLPI. Многие плагины держат собственный кеш в отдельных файлах, вне этого механизма, и в таких случаях --context=plugin:nome на них никак не влияет. Если после полной очистки поведение сохраняется, поищите файлы кеша самого плагина в каталоге files/_cache.

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

Почему не видно кнопок очистки

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

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

То есть: дело не в правах, не в версии и не в ошибке. Дело в режиме сессии.

Как включить режим отладки

Режим задаётся в профиле пользователя, а не в глобальной настройке:

  1. Нажмите на своё имя в правом верхнем углу и откройте Настройки.
  2. Найдите поле Использовать GLPI в режиме.
  3. Переключите Обычный на Отладка и сохраните.
Экран настроек GLPI с выделенным полем «Использовать GLPI в режиме», где режим переключается с «Обычный» на Debug
Поле находится в середине пользовательских настроек, сразу под языком, и отображается только для административных профилей.

Два важных замечания. Первое: это поле отображается только для пользователей с профилем администратора. Если вы его не находите, обратитесь к администратору среды. Второе: в режиме отладки GLPI показывает техническую информацию на многих экранах и добавляет нагрузку на обработку. Вернитесь в обычный режим, как только закончите, особенно в продуктивной среде.

Очистка через интерфейс

С включённым режимом отладки перейдите в Настройка > Общие и откройте вкладку Производительность. Теперь три блока отображаются с кнопкой очистки, и каждая очищает только свой кеш.

Вкладка «Производительность» в GLPI с тремя блоками кеша, у каждого своя кнопка «Очистить»
При включённом режиме отладки у каждого блока появляется собственная кнопка «Очистить».

Если после сохранения настройки кнопки всё ещё не появились, перезагрузите страницу настроек. Вкладка производительности загружает содержимое асинхронно, и она могла быть отрисована до смены режима.

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

Очистка из командной строки

У кого есть доступ к серверу, есть и более прямой путь, не требующий ни режима отладки, ни интерфейса. В корне инсталляции GLPI:

# limpa todos os contextos de cache
php bin/console cache:clear

Команда позволяет ограничить область действия, что предпочтительнее в продуктивной среде по той же причине, что и в предыдущем разделе:

# limpa apenas o cache de traduções, o caso mais comum
php bin/console cache:clear --context=translations

# limpa apenas os dados de usuário
php bin/console cache:clear --context=core

# limpa o cache de um plugin específico
php bin/console cache:clear --context=plugin:nome_do_plugin

Предосторожность, которая избавит от головной боли: запускайте команду от того же пользователя, под которым работает веб-сервер (обычно www-data или apache). Запуск от root пересоздаёт файлы кеша, принадлежащие root, и веб-сервер больше не может в них писать, что превращает временную проблему в постоянную.

Стоит отметить, что cache:clear работает с кешами, которыми управляет GLPI. Кеш опкодов PHP принадлежит самому расширению и сбрасывается при перезагрузке службы PHP-FPM.

Какой кеш очищать при каждом симптоме

Что происходитКакой кеш очищать
Текст остаётся на старом языке после обновления плагинаПереводы
Добавленный вами новый перевод не отображаетсяПереводы
Изменение в файле .php не даёт эффектаОпкоды (PHP)
Настройка сохранена, но экран показывает прежнее значениеПользовательские данные
Меню или пункт плагина не исчезает после удаленияПользовательские данные

А в GLPI 12?

Если сравнить код обеих версий, описанный здесь метод полностью действует и в GLPI 12: те же три кеша, те же контексты core и translations, то же требование режима отладки для появления кнопок и та же консольная команда. Каталог на диске следует схеме линейки 11, с версией в имени, например files/_cache/12.0.0-rc1-08464f22-production/.

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

Первое касается памяти. В GLPI 12 очистка кеша перестала выполнять предварительную компиляцию шаблонов, с явным обоснованием прямо в коде: шаблонов больше 400, и прогрев всех сразу превышал стандартный лимит памяти PHP. Вместо этого каждый шаблон компилируется при первом открытии страницы. На практике это делает очистку легче и надёжнее, но переносит затраты на того, кто первым откроет каждый экран после очистки.

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

Обманчивый случай: экран переведён наполовину

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

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

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

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

Меры предосторожности в продуктивной среде

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

  • Очищайте конкретный кеш, а не всё сразу. Симптом почти всегда указывает на один.
  • Избегайте часов пиковой нагрузки при очистке кеша опкодов, а в GLPI 12 — и при общей очистке кеша, поскольку шаблоны компилируются при первом обращении к каждому экрану. Перекомпиляция происходит по требованию, поэтому затраты ложатся именно на тех, кто в этот момент работает в системе.
  • Не оставляйте режим отладки включённым. Помимо нагрузки, он показывает на экране технические детали среды.

Когда проблема не в кеше

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


Проверено командой NexTool Solutions.

Часто задаваемые вопросы

Нет. Кеш — это временная копия того, что GLPI умеет восстановить. Настройки, заявки, активы и правила хранятся в базе данных и не затрагиваются. Единственный побочный эффект — кратковременное замедление, пока кеш перестраивается.

Рекомендуемой периодичности нет. Кеш не чистят регулярно «для гигиены»: в большинстве случаев он инвалидируется сам. Очищайте его, когда есть конкретный симптом, и только соответствующий кеш.

Для кешей, которыми управляет GLPI, нет. Для кеша опкодов PHP в большинстве инсталляций об этом уже заботится кнопка в интерфейсе; в средах, где PHP работает в отдельном процессе, перезагрузка службы PHP-FPM даёт тот же эффект.

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

Нужна помощь?