Профилирование и отладка кода

Профилирование и отладка кода

Если вы разрабатываете приложение/проект или занимаетесь поддержкой уже написанного кода или существующего проекта, то скорее всего вы уже используете профилировщик или отладку кода для поиска и устранения “узких” мест, которые могут создавать не очевидную на первый взгляд нагрузку. Хотя описанное ниже решение или проблема может относиться не только к разработчикам, но и к собственникам проектов.

Вариантов, как отладить свой код достаточно много и все они весьма разнообразны и каждый из вариантов подходит для определенного круга задач. В моём случае поиск “камней” в коде за частую происходит на работающем проекте, который в какой то момент времени перестает корректно работать и по этому поводу возможно стоит написать отдельно, так, как есть наиболее частые ошибки, которые обычно начинают появляться в момент роста проекта, когда количество посетителей возрастает в сотни, а то и в тысячи раз, и приходится строить архитектуру приложения/проекта уже с учетом текущих и будущих потребностей.

 

Blackfire

Что такое Blackfire? Blackfire это инструмент управления производительностью проекта, отладка кода на всех жизненных этапах: разработка, тестирование или продакшн. Почему Blackfire? Потому, что 0% нагрузка на сервер, запускается только по требованию и только для текущего сеанса и это очень важно, особенно, когда требуется протестировать и отладить функцию или страницу на проекте который сейчас работает под нагрузкой (продакшн). Есть инструменты для тестирования из командной строки, а так же, через плагин в браузере, что очень удобно, дополнительным бонусом есть SDK для интеграция в код приложения, где можно отдалить абсолютно все (будет ниже пример, как отладить работу чекаута). Из дополнительных плюшек есть автоматический запуск тестов, интеграция в Gitlab, GitHub, Bitbucket, NewRelick, Slack, Hipchat и еще много, много чего, что позволит: отлаживать, тестировать, реагировать и улучшать ваш код.

 

Зачем и для чего отлаживать код

Если вы разработчик, то кроме архитектуры приложения вас еще интересует его производительность, правильно ли был спроектирован код, что и где происходит на всех этапах работы кода под нагрузкой в конкретных или спонтанных (не определенных ранее в тест-кейсах) условиях.

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

  • I/O Wait – время затраченное на работу HDD. Если ваше приложение работает  с файловой системой: чтение, запись, поиск файлов или поиск контента по файлам, эта метрика будет очень полезна. Если взять пример работы той же Magento 1 или 2 то можно увидеть нагрузку на HDD когда происходит сборка xml файлов из этого может последовать очевидный вывод – используйте SSD диск.
  • CPU Time – процессорное время.
  • Memory – объем ОЗУ которое потребляет приложение. Этот параметр может увеличиться или уменьшаться по разным причинам. Функции которые наиболее часто попадают в “топ” расхитителей памяти: unserialize, array_value, base64_decode – список не полный и варьируется в зависимости от того,какие задачи решает приложение
  • Network – объем информации переданной/принятой по сети интернет
  • HTTP – запросы. Если приложение использует внешние сервисы типа: SOAP, REST или другие, это поможет выявить медленные запросы. Одной из частых проблем в “медленном” коде является использование сторонних сервисов, работу которых нет возможности контролировать, а не которые из них в какой то момент просто перестают работать или становятся очень медленными и в месте с ними ваше приложение
  • SQL Queries – наверное одно из самых уязвимых мест в коде, когда требуется детально анализировать каждый запрос, его влияние на работу приложения и системы в целом. Приходится принимать решение о возможности оптимизации запроса, а так же функции которая обрабатывает данные или вовсе о необходимости отказаться от запроса/функции.

 

Timeline – инструмент для визуального анализа работы функций

 

 

Пример подключения SDK для отладки функций чекаута в Magento

Полная документация, а так же варианты использования есть тут

Установку самого SDK я пропущу, так как эта информация есть в документации см. выше, единственное, что напишу, так это то, что все внешние библиотеки, которые использую для Magento 1 я копирую и перемещаю в папку vendor, по этому в этом примере путь к библиотеке будет лежать, через эту папку.

Более, чем в 90% случаев, интернет-магазины на Magento предпочитают использовать чекут (страницу оформления заказа) сторонних производителей плагинов для этой платформы и это связано не с ограниченной функциональностью “родного” чекаута, а больше с юзабилити и дружественным интерфейсом для клиента.

Пример простого отчета и рекомендаций для страницы товара.

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

<?php

/**
 * Add Blackfire profile
 */
require_once Mage::getBaseDir() . '/vendor/autoload.php';

/**
 * Onepage controller for checkout
 *
 * @category    Mage
 * @package     Mage_Checkout
 * @author      Magento Core Team <core@magentocommerce.com>
 */
class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
{

    /**
     * Checkout page
     */
    public function indexAction()
    {

        // create a configuration
        $config = new \Blackfire\ClientConfiguration();
        $config->setClientId('client-id');
        $config->setClientToken('client-token');

        $blackfire = new \Blackfire\Client($config);

        // create as many profiles as you need
        $probe = $blackfire->createProbe();


        if (!Mage::helper('checkout')->canOnepageCheckout()) {
            Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));
            $this->_redirect('checkout/cart');
            return;
        }
        $quote = $this->getOnepage()->getQuote();
        if (!$quote->hasItems() || $quote->getHasError()) {
            $this->_redirect('checkout/cart');
            return;
        }
        if (!$quote->validateMinimumAmount()) {
            $error = Mage::getStoreConfig('sales/minimum_order/error_message') ?
                Mage::getStoreConfig('sales/minimum_order/error_message') :
                Mage::helper('checkout')->__('Subtotal must exceed minimum order amount');

            Mage::getSingleton('checkout/session')->addError($error);
            $this->_redirect('checkout/cart');
            return;
        }
        Mage::getSingleton('checkout/session')->setCartWasUpdated(false);
        Mage::getSingleton('customer/session')->setBeforeAuthUrl(Mage::getUrl('*/*/*', array('_secure' => true)));
        $this->getOnepage()->initCheckout();
        $this->loadLayout();
        $this->_initLayoutMessages('customer/session');
        $this->getLayout()->getBlock('head')->setTitle($this->__('Checkout'));
        $this->renderLayout();


        $profile = $blackfire->endProbe($probe);
    }


}

 

Вверху класса мы подключаем библиотеку Blackfire, далее в функции происходит настройка профилировщика. Вместо clien-id, client-token потребуется ввести ваши данные, которые выдает Blackfire для своих клиентов (вам потребуется оформить подписку – платно или воспользоваться пробной версией).

Начало профиля $probe = $blackfire->createProbe();

Завершение $profile = $blackfire->endProbe($probe);

 

Выводы, заключение

Blackfire помогает выявить узкие места в коде, при этом основным преимуществом является использование его на продкшн-сервере. Использование например того же xDebug не возможно, по причине очень большого overhead, а так же отсутствие UI для определения, поиска и анализа используемых функций. В сети есть бесплатные инструменты, но они капля в море информации с которой приходится иметь дело, да и для поиска проблемы необходимо время, порой уходят десятки часов, и нужно принять тот факт, что на это время работа сервера будет парализована.

Так же есть сервисы Newrelic и Tideways, но они больше используются для мониторинга, чем для отладки и о них стоило бы написать отдельно, в чем их преимущества и различия.

В целом стоит разделять такие понятия, как, отладка, мониторинг и тестирование. Для всего есть свои инструменты, каждый обладает своими преимуществами и не достатками, есть пассивные и активные методы обнаружения ошибок.

По всем интересующим вас вопросам отладки и тестирования кода вы можете связаться с нами, используя контактную форму на сайте.