Статьи

Расширенный профилирование CodeIgniter с XHProf

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

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

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

Это руководство поможет вам установить XHProf на ваш сервер и интегрировать его с вашим приложением CodeIgniter с помощью хуков, чтобы вы могли сразу приступить к профилированию своего приложения в производственной среде. Все, что вы видите здесь, было написано для Ubuntu 10.04 — последней версии LTS на момент написания.


Установка XHProf может быть осуществлена ​​через PECL — тем не менее, я никогда не мог легко установить версию PECL в Ubuntu, поэтому ее проще установить из исходного кода. Начните с загрузки последней версии из учетной записи XHProf GitHub.

1
wget https://github.com/facebook/xhprof/tarball/master -O xhprof.tar.gz

Распакуйте архив и переключитесь в извлеченную папку — это изменится в зависимости от последней версии, доступной на GitHub.

1
2
tar -xvf xhprof.tar.gz
   cd facebook-xhprof-bc8ef04/extension

Затем установите как обычно.

1
2
3
4
phpize
   ./configure
   make
   sudo make install

Наконец, нам нужно сказать PHP, чтобы загрузить расширение. Создайте для него файл конфигурации — я делаю это для чистоты, но вы всегда можете оставить его в конце вашего основного php.ini .

1
sudo nano /etc/php5/conf.d/xhprof.ini

И вставьте следующее:

1
2
extension=xhprof.so
   xhprof.output_dir=»/var/tmp/xhprof»

Это говорит XHProf использовать каталог в /var/tmp/xhprof для сохранения своих данных запуска.

Вы можете проверить правильность установки XHProf, введя php -m в командной строке и проверив, доступен ли модуль. Не забудьте перезапустить Apache, чтобы его можно было использовать и в ваших веб-приложениях PHP.

Если вы хотите визуализировать изображения callgraph, вам также понадобится пакет graphviz. Это можно получить из кв.

1
sudo apt-get install graphviz

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

1
sudo mv ~/facebook-xhprof-bc8ef04 /var/www/xhprof

CodeIgniter имеет отличный механизм для вставки пользовательского кода в выполнение страницы под названием «Хуки». Это то, что мы будем использовать для интеграции XHProf с вашим приложением. Включите хуки в вашем файле application/config/config.php .

1
$config[‘enable_hooks’] = true;

Затем укажите ваши хуки в application/config/hooks.php

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
$hook[‘pre_controller’] = array(
     ‘class’ => ‘XHProf’,
     ‘function’ => ‘XHProf_Start’,
     ‘filename’ => ‘xhprof.php’,
     ‘filepath’ => ‘hooks’,
     ‘params’ => array()
   );
 
   $hook[‘post_controller’] = array(
       ‘class’ => ‘XHProf’,
       ‘function’ => ‘XHProf_End’,
       ‘filename’ => ‘xhprof.php’,
       ‘filepath’ => ‘hooks’,
       ‘params’ => array()
   );

Затем создайте ловушку, которая загрузит XHProf в ваше приложение по адресу application/hooks/xhprof.php . Этот класс обеспечит необходимый минимум для сбора данных XHProf из вашего приложения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class XHProf {
 
       private $XHProfPath = ‘xhprof/’;
       private $applicationName = ‘my_application’;
       private $sampleSize = 1;
       private static $enabled = false;
 
       public function XHProf_Start() {
           if (mt_rand(1, $this->sampleSize) == 1) {
               include_once $this->XHProfPath .
               include_once $this->XHProfPath .
               xhprof_enable(XHPROF_FLAGS_NO_BUILTINS);
 
               self::$enabled = true;
           }
       }
 
       public function XHProf_End() {
           if (self::$enabled) {
               $XHProfData = xhprof_disable();
        
               $XHProfRuns = new XHProfRuns_Default();
               $XHProfRuns->save_run($XHProfData, $this->applicationName);
           }
       }
 
   }

В этом примере кода есть несколько моментов, на которые следует обратить внимание.

  • $XHProfPath должна указывать на каталог, в который вы установили XHProf. В нашем примере мы помещаем его в корень веб-приложения, но вы можете хранить его где-то в центре и символьную ссылку на несколько приложений.
  • Переменная $applicationName позволяет вам указать имя приложения, используя XHProf. Это может быть особенно важно в среде, где вы запускаете несколько приложений на одном сервере.
  • $sampleSize позволяет вам указать коэффициент частоты выполнения профилей XHProf. В производственной среде, где вы получаете тысячи просмотров, вероятно, не стоит хранить каждый прогон. Вы можете увеличить эту переменную, чтобы получить случайную выборку прогонов. Например, изменив его на 10, вы получите отчет об одном из каждых 10 посещений вашего приложения.

Функция xhprof_enable() может принимать любую комбинацию из 3 констант.

  • XHPROF_FLAGS_NO_BUILTINS — пропустить все внутренние функции php. Добавление этого означает, что вы будете видеть только время, потраченное на функции, которые вы написали (или являетесь частью CodeIgniter)
  • XHPROF_FLAGS_CPU — добавить дополнительную информацию о профилировании процессора
  • XHPROF_FLAGS_MEMORY — добавить дополнительную информацию о профилировании памяти

Объедините их, используя + . например. xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_MEMORY);

Пройдя несколько раз через ваше приложение, наведите браузер на каталог приложения XHProf http://localhost/xhprof/xhprof_html/index.php — с учетом адреса вашего сервера разработки — и вы увидите список ваших Последнее приложение запускается с самым новым наверху. Выберите один из прогонов, чтобы увидеть информацию о профилировании.


Хранение всей этой информации профилирования очень хорошо и хорошо, но знание того, как ее оценить, является ключом к оптимизации вашего приложения.

«Общее резюме» — хорошее место для начала — оно покажет вам:

  • Общее время включения — сколько времени (в микросекундах) потребовалось для создания вашей страницы
  • Общее использование памяти — общий объем памяти, использованный этим прогоном вашего приложения
  • Общее пиковое использование памяти — максимальный объем памяти, используемый вашим приложением
  • Количество вызовов функций — количество функций, которые были вызваны вашим приложением
Выполнить резюме

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

Ниже краткого отчета приведен подробный отчет о выполнении. Узкие места в вашем приложении должны быть достаточно очевидными — это вызовы функций в верхней части отчета.

Настенный отчет

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

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

При отладке приложения CodeIgniter одним из лучших мест для запуска является вызов контроллера для вашей страницы — Welcome::index в примере. Оттуда вы можете легко увидеть, где контроллер провел большую часть своего времени.

Резюме контроллера

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

граф вызовов

XHProf предоставляет механизм для сравнения нескольких прогонов — это позволит вам сделать ряд оптимизаций, а затем посмотреть, как они повлияли на ваше приложение.

http://localhost/xhprof/xhprof_html/index.php?run1=run_id_1>&run2=run_id_2&source=applicationName

Примечание: run_id_1 и run_id_2 должны быть идентификаторами некоторых из ваших предыдущих запусков, а applicationName должно быть именем, которое вы указали при настройке перехватчика ранее.

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

Иногда одного прогона может быть недостаточно, чтобы точно оценить, что происходит. Страницы могут работать по-разному, в зависимости от строки запроса или пользовательского ввода, иначе могут быть различия в механизмах кэширования.

Агрегирование нескольких прогонов позволяет объединить несколько прогонов и получить среднее значение потребляемых ресурсов.

http://localhost/xhprof/xhprof_html/index.php?run=run_id,run_id,run_id&source=applicationName

Примечание: run_id должен быть идентификатором из некоторых ваших предыдущих запусков, а applicationName должно быть именем, которое вы указали при настройке перехватчика ранее.


Теперь у вас должен быть запущен и запущен XHProf в вашем приложении CodeIgniter, и вы сможете точно определить, где ваш код тратит большую часть своего времени. Оптимизация может быть сложной задачей. Иногда это не так просто, как переопределение функции или добавление слоя кэширования. Размышление о том, почему вы что-то делаете и как точно влияет на ваше приложение, не менее важно.

Так что дайте мне знать, если у вас есть какие-либо вопросы в комментариях ниже. Большое спасибо за чтение!