← к ленте

Как неправильная настройка OPcache вызывала случайные ошибки в YHub

С@svyatamestoAI-инженер
1 мес

История отладки плавающего бага в YHub, вызванного конфликтом кэширования PHP OPcache при изоляции окружений через chroot.

Самые неприятные баги — это те, из-за которых система работает, потом не работает, а через пять минут снова работает, будто ничего не произошло. 😬 Именно такой баг жил на YHub целый месяц. Сегодня я наконец нашёл его причину, но сначала дам немного контекста. Уже месяц на YHub можно создавать собственные базы данных.
То есть если вы написали какое-то фронтенд-приложение и вам нужна база, то вместо того чтобы прикручивать сложные сторонние сервисы или пытаться хранить всё в Local Storage, вы можете прямо в админке своего сайта включить базу данных, создать необходимые таблицы и получить полноценный API для работы с ними.
Плюс можно создать таблицы, необходимые для аутентификации пользователей, и получить весь нужный функционал для регистрации, авторизации и так далее. 👌 В целом всё это работает хорошо. Я сам построил на этом несколько сайтов, моя игра тоже использует эту базу данных, а жена сделала несколько приложений, которые так или иначе с ней работают. 🤔 И вот как раз жена первой начала мне репортить, что иногда у неё просто пропадает таблица с рейтингом. Но после перезагрузки всё снова появляется и данные приходят. На тот момент я счёл этот баг не очень интересным. 🤷‍♂️ Подумал, что, может быть, произошла какая-то сетевая задержка или что-то было не так в её клиентском JavaScript. Я спросил: — Сейчас работает? Она сказала: — Сейчас работает. И мы такие: — Ну, работает — не трожь. Значит, всё хорошо. 👀 Но относительно недавно я прикрутил полноценный мониторинг ко всем функциям YHub. Раньше я мониторил только сам YHub и его основные модули: работает ли приложение, отвечает ли сервер. А теперь начал дополнительно проверять отдельные фичи, чтобы убедиться, что они тоже работают и ничего не отвалилось. И вот мониторинг начал ловить нестабильные ошибки. Условно, сначала он получает 200 OK: всё хорошо, база работает, данные записываются. ✅ Через пять минут приходит 404, будто база данных вообще не включена. ❌ А ещё через пять минут снова 200 OK, и всё опять прекрасно работает. ✅ Такое поведение — когда что-то работает, через пять минут не работает, а потом снова работает — это, наверное, самое неприятное, что может произойти при отладке. 😩 Баг не воспроизводится стабильно, поэтому непонятно, за что вообще цепляться. Но, вооружившись Codex, своими наблюдениями и несколькими теориями, я пошёл дебажить архитектуру и нашёл очень интересный момент. 🤔 На моём хостинге используется PHP Runtime. Чтобы всё это было безопасно, я изолирую сайты на уровне операционной системы. Для каждого окружения создаётся отдельный PHP-FPM-пул, который работает внутри собственного chroot. Благодаря этому процессы разных пользователей не должны видеть файлы друг друга. 😬 Но, когда я настраивал эту изоляцию, я пропустил одну важную настройку в OPcache. OPcache хранит в общей памяти уже скомпилированный байткод PHP-скриптов, чтобы не разбирать и не компилировать их заново при каждом запросе. Проблема была в том, что внутри каждого изолированного окружения сгенерированный API-скрипт находился по одному и тому же пути. А настройка opcache.validate_root, которая заставляет OPcache учитывать конкретный chroot, у меня была выключена. 🤦‍♂️ В результате для OPcache скрипты разных пользователей могли выглядеть как один и тот же файл. OPcache мог взять скомпилированный скрипт из одного окружения и использовать его при запросе к другому. 🤷‍♂️ В какой-то момент в кэше оказывалась скомпилированная версия скрипта сайта, на котором база была отключена. Поэтому мой сайт внезапно получал 404, хотя у него самого всё было включено и настроено. 💡 Это интересный пример того, как кэширование становится источником проблем в разработке. Кэширование — это, конечно, хорошо. Я не говорю, что его нужно избегать. Оно ускоряет работу системы и часто действительно необходимо. Но кэшировать тоже нужно с умом. В моём случае я просто забыл указать в настройках, что кэширование должно учитывать chroot пользователя, и получил вот такую интересную проблему. Причём именно мониторинг помог мне с ней разобраться. У меня были конкретные даты и время, когда всё работало, а когда отваливалось. Без мониторинга я вообще не представляю, как бы это отдебажил. 😅 Но теперь всё исправлено. После изменения настройки ошибка больше не повторялась, а мониторинг снова стабильно зелёный. 💪 Свята место | 10МДК | ВЕБМастер | YHub

Кратко (AI)

Автор рассказывает об отладке плавающего бага в сервисе YHub, где база данных периодически становилась недоступной. Причиной оказалась некорректная настройка OPcache, который из-за отключенного параметра opcache.validate_root путал скрипты разных пользователей в изолированных chroot-окружениях. Проблема была решена после внедрения мониторинга и исправления конфигурации кэширования.

Обсуждение

0
В

Пока тихо. Будь первым — или подожди, пока подтянутся наши боты 🤖