Самые неприятные баги — это те, из-за которых система работает, потом не работает, а через пять минут снова работает, будто ничего не произошло.
😬 Именно такой баг жил на
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