Воскресный пост без технических нюансов. Просто история одного дня из жизни команды разработки. Пост для развлечения и поднятия боевого духа перед началом рабочей недели – все решаемо и всегда есть выход из ситуации, главное его найти.
Акт первый. Предыстория
У одного из наших заказчиков есть сайт, который работает на cms-ке wordpress с кучей плагинов, в том числе wooCommerce для каталога товаров и онлайн продаж. Под капотом страшновато, но проект свои функции выполняет – много уникального контента, красивые картинки/видео, каталог товаров, можно сделать онлайн заказ. Долгое время сайтом управляли как конструктором, в код никто не лазил, а все доработки логики происходили через добавление готовых плагинов. И когда их количество набрало критическую массу, дорабатывать что-то через добавление новых или настройки установленных, стало невозможно. К тому же сайт рос и стали появляться новые ожидания и идеи, которые нельзя реализовать без доработок кодовой базы. Тогда мы – отдел разработки, и подключились. Первое время было страшновато что-то менять, поскольку небольшие доработки в одном месте, могли сломать пару разделов на другом краю сайта. Но потихоньку разобрались и начали вносить изменения.
Спустя какое-то время, заказчик начал готовить большую маркетинговую акцию – предзаказ нового товара. Был предварительный серьезный разогрев аудитории через соц.сети, много кто проявил интерес и с нетерпением ждал старта продаж. Параллельно шла подготовка и на сайте: собрали красивую «продажную» страницу, добавили туда кнопки покупок, все в лучших традициях. Красиво. Все работает. И даже в срок.
Акт второй. Падение
Запуск запланировали на 12:00. Проверка всех систем – порядок. Ключ на старт и поехали! Ссылки на страницу публикуются в ВК, ютуб, почтовая рассылка и тд. Сразу же полетели заказы, оплаты проходят, сайт держится. Пять минут – полет нормальный. Трафик посетителей, если судить по метрике, скакнул примерно в 20-25 раз относительно спокойных дней.
12:07, сайт падает. Караул! Семь минут всего продержались. В чем дело? Бегом разбираться. Сервер выкидывает 504ю ошибку – лютые таймауты. На хостинге нагрузка запредельная, до 500% перерасход допустимых ресурсов. В консоле карнавал из подвисших процессов php. «Убиваем» руками самые долгие процессы. Параллельно перепроверяем код страницы, вырезаем все запросы к базе данных, которые не критичны и меняем значения на статичные – счетчик продаж, просмотров и тд. Пол часа и сайт снова заработал, пропали 504е, но страницы открываться со скрипом, явно что-то не так. Еще 10 минут и сайт снова падает – процессы подвисают и насилуют процессор на всю катушку. Пока ищем в коде, что еще можно быстро оптимизировать, руками чистим процессы, чтобы сайт хоть как-то держался. Трафик посетителей в это время только растет.
Акт третий. Бан от хостинга
13:30 хостинг выписывает бан и блокирует доступ к сайту. Из-за перерасхода ресурсов, хостер автоматически наложил блокировку. И теперь при входе на сайт стала появляться серверная basic auth авторизация, которая не пускает никого на сайт. Трафик идет на сайт, а он не работает. Срочно нужно решать проблему. Самое понятное – докупить ресурсов. Бегом к хостеру повышать тариф. Но автоматика не дает обновить тарифный план, если есть блокировка по нагрузке. Странновато. Пишем в поддержку, просим поднять тариф и снять блокировку. Саппорт молчит, сайт лежит. Звоним. Описали проблему, договорились – все ок. Бан нам сняли и тариф подняли. Сайт ожил, но не на долго. Победили последствия, а не причину. Ищем дальше, что может создавать такую серьезную нагрузку и один за другим вешать процессы. Идей нет, все сделано хорошо, если мерить рамками вордпресса. Плагины кеширования все включены, но они кешат только статику. Быстренько накидываем логику кеша запросов к базе. Пока разбирались и дописывали кеш, сайт снова падает. Апаем доработки с кешем, убиваем процессы. Сайт запускается, но работает все так же с жуткими тормозами. Кеширование явно не помогло. Еще пол часа и ловим новый бан от хостинга, поскольку израсходовали ресурсы и от более высокого тарифа.
Акт четвертый. Хацкеры
Блокировка сайта хостингом проходила просто добавлением basic auth. Но авторизация какая-то странноватая оказалась. Логин и пароль были admin и admin. Это оказалось тоже проблемой. В соц.сетях люди стали обсуждать падение сайта и проблему, что нельзя купить анонсированный товар. Активисты начали писать рекомендации, как починить и что проверить. А самые шустрые подобрали доступ и скинули его всем в комментариях. И тогда даже на заблокированный сайт стали заходить посетители о оформлять заказы. Но сайт закрыт не только для пользователей, а и для всех сервисов, которые пытаются достучаться. В том числе и банковские колбеки, которые должны приходить на сайт после успешной оплаты, делать отметку на сайте и обновлять статус заказа. Так помимо проблем с нагрузкой, добавилась беда с оплатами – деньги списываются, а заказы висят в статусе «ожидает оплаты».
Антракт
Быстрые фиксы не помогают, нужно искать кардинальное решение. И мы решаем закрыть полностью доступ к сайту и быстренько перенести его на свой сервер, который для отладки используется. Тестовый сервер у нас помощней клиентского боевого раза в 2-3. Плюс на своем серваке мы имеем полный доступ, в отличии от хостинга, который даже логи не все предоставляет. Идея казалась адекватной: перенести к себе, линконуть по-быстрому домен через а-записи, которые обновляются за 10 минут, открыть доступ и полноценно отдебажить, понять в чем дело.
За пару часов перетащили файлы, код и базу. Запускаем сайт, с надеждой, что ресурсов сервера хватит, чтобы продержаться, пока мы хотя бы локализуем проблему.
Сайт заработал, но страницы открываются еще медленнее. Такого поворота даже и предположить не могли. Процессор в 4-5 раз мощнее, оперативки в два раза больше. В чем дело? Дело в жестком диске. На тестовом сервере HDD, нам больше важен объем чем скорость. Хоть скорость hdd серьезно уступает ssd, но она не должна так влиять на скорость отдачи контента. А все запросы к базе данных, что есть на посадочной странице, мы закешировали.
Акт пятый. Да ладно?
Начинаем смотреть все подряд запросы, что происходят в вордпрессе. Ужас, несколько сотен запросов на каждой странице. Каждый плагин, который установлен, и даже не используется, делает какие-то свои запросы на чтение и на запись. Разобрать, что нужное, а что лишнее, просто не реально сходу. Нужно анализировать каждый плагин и его запросы, просто так отключить или закешировать не получается – сайт начинает падать.
Приходит две идеи: отвязать страницу от вордпресса и на время показывать статику, и перенести базу данных сайта в оперативку, чтобы заработала быстрей, чем на hdd. Занялись параллельно двумя решениями.
Время 21:30. Мысли начинают путаться, а пальцы промахиваются по клавишам. Одно неверное движение и при переносе БД в виртуальный диск, который сделали из оперативки, меняются настройки прав на файлы бд. База умирает. Реанимация не помогает. Возвращаем файлы БД наместо на hdd, перезапускаем mysql, а он не стартует и падает с ошибками. Доигрались. На сервере, помимо тестовых сайтов еще и рабочий таскменджер развернут, он тоже мертв. Через режим реанимации(innodb_force_recovery) запускаем mysql и пытаемя убить БД от сайта, который пытались оживить. Структура таблиц видна, объем данных тоже, но сами данные не доступны и удалить всю БД нельзя. Решили снести самые «тяжелые» таблицы и попробовать еще раз перезапустить mysql. И тут натыкаемся на таблицу весом 2 гб. Интересненько, это 80% веса всей базы данных. А что там? Логи. Логи плагина от почтового сервиса мейлчимп.
Кое-как удаляем базу данных, перезапускаем mysql – ожил. С рабочего хостинга стягиваем еще раз базу данных к себе на сервер и запускаем без махинаций с виртуальным диском в оперативке. Полезли смотреть, что за логи и откуда такой объем. Оказывается, отключенный плагин для отправки почты, собирает каждое действие пользователя на сайте и сохраянет их БД. Самое интересное, что плагин был установлен давным-давно и так же давно отключен. Но это ему не мешало потихоньку заполнять базу данных, будучи деактивированным.
Удаляем мусор из БД, удаляем код плагина, стартуем сайт и о чудо, никаких тормозов. Работает даже в 2-3 раза быстрей, чем раньше в спокойные времена. На всякий случай проверяем нагрузку, а ее нет совсем. Дальше дело техники: возвращаем сайт на хостинг заказчика и открываем доступ.
Время 22:51. Сайт снова запущен и полноценно функционирует. Покупатели в соц.сетях снова активизировались и побежали оформлять заказы. Нагрузка на хостинге в пределах нормы. Все довольны. А мы уползаем по домам отсыпаться.
Занавес
Мораль истории такова, что нужно осторожно использовать плагины. А при отладке стоит посмотреть по сторонам, проблема может быть не там, где ее ищешь.
Комментарии (7)
DjPhoeniX
10.12.2023 17:09Сразу в голову пришла мысль посмотреть диагностику БД. Обычно «топ самых дорогих (по cpu/ram/storage) запросов» сразу показывает, что и откуда надо выпилить. Так и недостающие индексы находятся, и кандидаты на кэш, и даже просто криво написанное.
gruzoveek
10.12.2023 17:09Ох уж этот вордпресс. Напоминает как будто на пустыре построили ну допустим киоск роспечать. А потом к нему приделали лоток с овощами. А потом цветочный киоск. Шаурмяченую. Хостел. И через полгода там такой шанхай, трущобы и фавелы, что черт ногу сломит. И еще морду набьют если зайдешь не туда.
Имел я как-то опыт работы с этим монстром, примерно в таких же исходных, что описывает ТС. Плюс там еще автор был одержим понапихать в один проект как можно больше технологий, поэтому плюсом шла дополнительная базёнка монгоДБ, некоторые места фронта были написаны на ангуляре, и где-то сбоку торчала интеграция с 1С. Все обильно утыкано плагинами трех сортов: скачанные, самодельные и скачанные но потом руками поправленные и никому не известные где и как.
И вот автор как то быстро куда-то уволился, он вообще энтузиаст, а меня послали сопровождать тот шанхай. Тормозило оно знатно. Как на бэке так и на фронте. Периодически что-нибудь отваливалось. Я еще своих пару плагинов написал и поубирал лишние бд, прежде чем сам уволился. Потом они там вроде как заказали на стороне нормальный интернет-магазин.
vlom88
10.12.2023 17:09Я правильно понимаю, вы пришли все пушистые, продали клиенту сопровождение и обслуживание, проработали маркетинговую компанию, судя по приросту заказов неплохую, но не удосужились собрать хоть какую-то статистику по производительности системы, посмотреть что куда ходит у вас, сколько запросов в БД на странице, не? Не говорю даже про какое либо минимальное нагрузочное тестирование.
А судя из текста у вас есть БД, в ней таблица раздутая по размерам с непонятными логами и это у вас не вызвало ни малейшего вопроса?
Мне просто интересен ход ваших действий при приёмке проекта в работу.
Ipatov_e Автор
10.12.2023 17:09Рекламой сам заказчик занимается, у них в соц.сетях хорошие по размеру группы и для емейл рассылок база большая. Мы только дизайн и разработку делаем. Нагрузку проверяли, но не детально - по метрикам хостинга треть ресурсов использовалось в спокойные дни, проблем с ней не было. И несколько подобных акций пережил сайт без проблем с падениями. Беда случилась, когда БД заполнилась логами достаточно, чтоб увеличить нагрузку до критической. Согласен, можно было и в обычное время заметить лишние записи в БД, но случилось так, что не заметили и поэтому в авральном режиме пришлось разбираться. В вордпрессе, особенно когда куча плагинов установлено, не так просто убрать лишние запросы к базе – все переплетено между собой и просто так отключить лишнее не получится без доработок и переделок.
Adward
10.12.2023 17:09Внесу свою лепту. Есть достаточно известный и популярный плагин.
All-In-One Security (AIOS) – Security and Firewall
Этот тоже любит раздувать базу логами. Я как то при анализе расходуемого места обнаружил, что у меня есть несколько БД от сайтов с 3-5 страницами, которые раздуты до 5-6 гигов. При этом нигде в настройках никак не ограничить время хранения логов
DimaLepel
Спасибо за интересную и поучительную историю. Очередной раз убеждаюсь, что плагины не всегда являются панацеей на все задачи. Иногда нужно и ручками что-то прописывать.
Ipatov_e Автор
Да, с плагинами нужно держать ухо востро. Их можно использовать, но нужно понимать как работают и какие еще дополнительные эффекты приносят. В каких-то ситуациях могут выручить, например, как с этим проектом из поста, на самом старте магазина заказчик все сам делал, без бюджета на разработку. Но когда проект становится большой и появляется серьезная нагрузка, неизвестные плагины могут устроить проблем.
То есть на каких-то этапах, когда ограничен бюджет, можно по-быстрому на плагинах "слепить", но с ростом проекта, лучше потихоньку приводить его в порядок, постепенно убирая лишнее и корректируя работающие куски.