Восемьдесят миллионов оттенков зеленого: как боты устроили распродажу производительности

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

b28ab97135cb63d752a7d9b9c792fadc.png

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

Дисклеймер

Прежде чем перейти к разбору кейсов, сделаю важное отступление. Да, я знаю о неоднозначном отношении к Битриксу, особенно когда речь идет о относительно крупных и нагруженных проектах. Конечно, грамотно написанный проект на современном фреймворке будет быстрее и технологичнее. Ключевое слово здесь — грамотно написанный. Интересно, сколько времени у вас уйдет на создание с нуля функционала, аналогичного БУС.

Конечно, найдутся специалисты, которые заявят, что реализуют это на WordPress или, прости господи, Joomla за вечер и пачку сигарет. Но, есть сомневаюсь в этом. Я уверен, что правильно настроенный Битрикс способен работать быстро и выдерживать средние руки. 

Если вы убежденный противник PHP и Битрикса в частности, или скорость для вас ассоциируется исключительно с Go, возможно, этот материал не для вас. Также если вы сеньор-разработчик Битрикса — вам здесь может быть не слишком интересно.

Кейс первый: Таинственное замедление

Первым пациентом стал проект на Битриксе, созданный на основе готового решения с серьезной кастомизацией. B2B-проект с интеграцией с 1С, каталогом около 10 тысяч товаров и примерно сотней свойств. Сервер у проекта был настоящий космолет — на таком не только сайты можно хостить, но и, пожалуй, космические корабли запускать.

Проект имел историю заражения вирусами, был не до конца обновлен, и, что самое критичное, работал катастрофически медленно. Карточка товара могла грузиться более 6 секунд, про списки товаров и главную страницу лучше было вообще молчать.

Первым делом мы обновили ядро и перевели проект на PHP 8.1, учитывая неуверенность в качестве предыдущей очистки от вирусов. Этот процесс имел свои нюансы, но сейчас не о них. Обновление, как и ожидалось, не решило проблему производительности. 

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

Дальнейшее расследование привело нас к таблице с 80 миллионами записей — таблице готового решения, хранящей названия корзин и их цвета. Это была реализация модного разделения корзин. Странность заключалась в том, что при минимальном трафике и закрытом характере портала такой объем данных казался необъяснимым.

Разгадка крылась в роботах — Яндекса, GPT, Apple и прочих. Система создавала для каждого бота отдельную сессию и автоматически генерировала корзину с зеленым цветом и названием по умолчанию. Решение оказалось простым — мы закрыли проект от ботов и добавили механизм очистки неактуальных корзин. Результат — время загрузки снизилось с 6 секунд до 0,04–0,06 секунд.

Кейс второй: Периодические падения сервера

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

Команда проекта уже провела определенную работу: настроили memcached, оптимизировали базу данных, экспериментировали с настройками 1С, но существенных улучшений это не принесло.

На первый взгляд заметили 300–400 запросов на страницу — многовато, но не критично. Init-файл оказался перегружен разнообразным функционалом, что противоречит хорошим практикам, но не критично. Команды для анализа логов помогли выявить активность ботов:

Первая команда выводит всех ботов в отдельный файл:

awk »{print $6}» bots.log | sort | uniq -c | sort -nr | head -n 1

Вторая команда сортирует ботов по количеству запросов:

awk -F\» »{print $6}» bots_sort.log | sort | uniq -c | awk »$1 > 5000» | sort -nr

Особенностью проекта оказалось необычное соотношение — на 100 тысяч товаров приходилось 10 тысяч свойств, что существенно выше нормы. Компоненты каталога не были оптимизированы под такой объем данных, а стандартный обмен с 1С только усугублял ситуацию.

При проверке конфигурации MySQL обнаружили, что кэш составлял всего пару гигабайт при доступных тридцати. Композитное кэширование было полностью отключено. В результате мощный сервер пытался обрабатывать 500–600 запросов на каждый хит, что в сочетании с медленной SQL создавало критическую нагрузку.

План оптимизации включил внедрение Cloudflare для контроля ботов, включение композитного кэширования, оптимизацию конфигурации MySQL, чистку неиспользуемых модулей, реструктуризацию init-файла и оптимизацию механизма работы со свойствами товаров — подключение Elastic или хранение данных в формате json в одной строке.

Главные уроки

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

Проблемы производительности часто имеют комплексный характер, затрагивая различные уровни системы — будь то Битрикс, Laravel или любая другая платформа. Иногда это некачественный код, иногда — неоптимальная архитектура. При этом диагностику всегда стоит начинать с проверки самых очевидных причин, постепенно углубляясь в детали. Удивительно часто решение лежит на поверхности — нужно только уметь его увидеть.

© Habrahabr.ru