Поступила мне тут на днях следующая задача, помочь решить проблему "сайт тормозит".
Краткое предисловие было в том, что время открытия заглавной страницы сайта составляло порядка 6-8 секунд , по словам клиента " сайт тормозит" ! При всем этом, ничего такого особенного и тяжеловесного на сайте нету. Задача интересная и не совсем обычная для меня и я решил взяться.
Сайт написан на YII который славится своей быстротой. Первичное исследование железа на котором установлен сайт показало VPS со следующими параметрами : 8 ядерный процессор, 32Гб ОЗУ, SSD диск . Причина скорее всего не в железе. Сайт работает под управлением PHP56 и NGINX в качестве СУБД выступает MYSQL 5.5. На всякий пожарный смотрим настройки mysql (а то тут был у меня один случай :) , все в порядке база на innoDB. Все размеры буферов и кэшей соответствуют размерам БД, да и обычный show processlist ни дает ничего криминального, как иногда это бывает.
Запускаем chrome посмотреть выдачу , показатель TTFB то есть время через которое браузер получил первый байт составляет 6.23 сек ! Причем повторные загрузки не изменили картины. При всем этом размер страницы всего 65Кб.
Проблема "сайт тормозит" явно в коде сайта !
Как спрофилировать код PHP ?
Проблема локализована, но не понятно, что именно так тормозит. Для того, чтобы это понять, я устанавливаю и запускаю XDEBUG. Включаем срабатывание xdebug по триггеру и настраиваем директорию куда он будет писать свой файл. Запускаем обновление главной страницы с параметром ?XDEBUG_PROFILE и любуемся файлом в 97MB )))
Для быстрого анализа файла выдачи Xdebug есть офигенский инструмент webgrind. Устанавливаем его с GITHUB репозитория и скармливаем ему наш 97Мб файлик. Убираем функции PHP и сортируем по Total Self Cost для начала. Это самый затратный процесс.
На первом месте вызов KatalogVavtoModule->generateItemsPathsMap. Самое частое кто его вызывает этоKatalogAvtoUrlRule->createUrl. Заглядываем внутрь, а там 1,5 млн. выполнений операции array_key_exists !!! Ныряем в код и проводим небольшое расследование. Итого: модуль KatalogAvtoUrlRule->createUrl переопределяет собственные методы CBaseUrlRule createUrl и parseUrl , для формирования ссылок на товары и категории товаров, в которых идет обращение к модулю KatalogVavtoModule и методу generateItemsPathsMap. Идем дальше в этот метод и видим следующую картину. Каждый раз при формировании ссылок выполняется поиск и выборка из БД более чем 11 тыс. строк, обработка и формирование карты ссылок которая затем скармливается createUrl и уже по этой карте формируется нужная ссылка.
На главной странице примерно 132 ссылки на различные категории и товары, 132 х 11 тысяч строк БД + операции проверки и формирования нужных ссылок. Вот то, что тормозило сайт ! Так как товары практически не меняются^ посещаемость сайта не велика и дабы не углубляться в дебри бизнес-логики, включаю кэширование и дописываю код. Теперь карта ссылок будет хранится в CFileCache и при всевозможных изменениях в категориях или товарах. Заново перестраиваться. Сказано сделано.
Стало 893ms !!! Победа !!!
Пишите в коментариях как Вы справлялись с похожими проблемами.