24 ноября 2010 г. FreeBSD PHP XHProf Оптимизация

FreeBSD. XHProf для анализа производительности PHP

Решил я воспользоваться утилитой для профилирования производительности веб-приложения XHProf от Facebook. И она мне так понравилась, что я решил написать про неё небольшой пост.

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

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

Профилирование в Wikipedia

Данные выводятся в виде таблицы:

Так же она может отрисовать граф с помощью GraphViz, но для этого он должен быть предварительно собран в системе (об этом ниже):

XHProf представляет собой pecl-расширение для PHP, написана она на си, поэтому достигается высокая с ее стороны производительность и ее можно использовать на продакшен сервере для анализа реальных данных.

Установка

Я собирал расширение из сорцов, для этого заходим на страницу расширения и качаем необходимую нам версию, у меня это xhprof-0.9.2:

cd /tmp
fetch http://pecl.php.net/get/xhprof-0.9.2.tgz
tar -xzf xhprof-0.9.2.tgz
cd xhprof-0.9.2/extension/
phpize
./configure --with-php-config=/usr/local/bin/php-config
make && make install

Пропишите расширение в php.ini или в php/extensions.ini:

extension=xhprof.so
Вы можете поставить расширение XHProf из портов (/usr/ports/devel/pecl-xhprof/).
В мае, когда я практически написал эту статью, его ещё там небыло.

Укажите в php.ini каталог, который будет играть роль хранилища ваших данных:

[xhprof]                                                   
xhprof.output_dir=/usr/local/xhprof/out

Ну и создать его тоже надо, естественно:

mkdir -p /usr/local/xhprof/out

XHProf UI

Теперь настроим веб-интерфейс XHProf, для этого скопируем сорцы в свой каталог:

mkdir /usr/local/xhprof/
cp -R /tmp/xhprof-0.9.2/ /usr/local/xhprof/

И пропишем новый хост в nginx:

server {
    listen 80;
    server_name xhprof.test;
    charset utf8;
    root /usr/local/xhprof/xhprof_html;
    index index.php;

    location ~ \.php$ {
        fastcgi_pass php-fpm;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Перезагружаем nginx:

nginx -s reload

А в локальном файле hosts завяжем домен:

123.45.67.89 xhprof.test

Где "123.45.67.89" - ip машины на которой стоит XHProf, то есть где мы его только что устанавливали.

Собираем Graphviz

Для построение визуализации соберем Graphviz (крайне рекомендую это сделать, будет намного нагляднее).

cd /usr/ports/graphics/graphviz
make install clean

Собираем Ctype

Вам так же может понадобится Ctype

cd /usr/ports/textproc/php5-ctype
make install clean

Настройка

Теперь настроим XHProf так, чтобы он профилировал только когда у нас установлена специальная кука. Для это создадим два файла "/usr/local/xhprof/header.php" и "/usr/local/xhprof/footer.php", со следующим содержимым:

1) Отредактируйте "/usr/local/xhprof/header.php":

<?php
if(isset($_COOKIE['xhprof'])){
    if (extension_loaded('xhprof')) {
        $utils_path = "/usr/local/xhprof/xhprof_lib/utils/";
        include_once $utils_path.'xhprof_lib.php';
        include_once $utils_path.'xhprof_runs.php';
        xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
    }
}

Он срабатывает только если установлена кука "xhprof", подключает необходимые библиотеки и устанавливает необходимые флаги (об этом чуть ниже).

2) Отредактируйте "/usr/local/xhprof/footer.php":

<?php
if(isset($_COOKIE['xhprof'])){
    if (extension_loaded('xhprof')) {
        $profiler_namespace = 'myapp'; // namespace for your application
        $xhprof_data = xhprof_disable();
        $xhprof_runs = new XHProfRuns_Default();
        $run_id = $xhprof_runs->save_run($xhprof_data, $profiler_namespace);

        // url to the XHProf UI libraries (change the host name and path)
        $profiler_url = sprintf('http://xhprof.test/index.php?run=%s&source=%s', $run_id, $profiler_namespace);
        echo '<a href="'.$profiler_url.'">Profiler output</a>';
    }
}

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

Теперь добавим в конец две строки в php.ini, для того чтобы эти два скрипта стартовали в начале и конце соответственно:

auto_prepend_file = /usr/local/xhprof/header.php
auto_append_file = /usr/local/xhprof/footer.php

Более подробная документация по XHProf: http://mirror.facebook.net/facebook/xhprof/doc.html

Проблема с dot

Утилита dot это тот самый Graphviz и с ним бывает проблема, что-то типа того:

Error: either we can not find profile data for run_id 4ced888563969 or the threshold 0.01 is too small or you do not have 'dot' image generation utility installed.
Сначала зайдите в "/usr/local/xhprof/xhprof_lib/utils/callgraph_utils.php" и найдите функцию "xhprof_generate_image_by_dot" (примерно 96 строка). Отредактируйте массив $descriptorspec, указав путь до файла лога:
$descriptorspec = array(
       // stdin is a pipe that the child will read from
       0 => array("pipe", "r"),
       // stdout is a pipe that the child will write to
       1 => array("pipe", "w"),
       // stderr is a file to write to
       //2 => array("file", "/dev/null", "a")
       // Путь до файла лога
       2 => array("file", "/var/log/xhprof.log", "a+")
       );
Ну и теперь запускайте и смотрите лог, если у вас там:
dot: not found

То просто укажите полный путь до dot:

$cmd = " /usr/local/bin/dot -T".$type;

Это примерно 107 строка того же файла "/usr/local/xhprof/xhprof_lib/utils/callgraph_utils.php".

Ссылки

Посты, от которых я узнал о XHProf:

Советую почитать:

Комментарии

А ссылки к статье умеешь работающие без шаманства указывать?

Ссори, это плагин обновился так неудачно... Спасибо.

Спасибо очень интересная тузла

Напишите пожалуйста еще про Pinba:
для mysql - /usr/ports/devel/pinba_engine
для php - /usr/ports/devel/php5-pinba

Года два назад у меня был черновик по Pinba, но потом мне что-то не понравилось в самой Pinba и я удалил черновик. А может это все лень :)

Тогда можно написать хоть про mariadb с портов

тут все есть cd /usr/ports/devel/pecl-xhprof; make install clean;

Кстати, юзал его вместе с Apache2, память течет из-за него. Как только отключаешь - сразу все нормально

Подскажите в связи с чем(сервер - Denwer под WinXP), не запускается dot.exe и выдается ошибка при инициализации приложения 0xc0150004 ну и соответственно в браузере выдает Error: either we can not find profile data for run_id 51c33d704a047 or the threshold 0.01 is too small or you do not have 'dot' image generation utility installed. Использую xhprof расширение под windows c http://dev.freshsite.pl/php-extensions/xhprof.html Данные с помощью xhprof в таблицу выводятся нормально, а вот Graphviz Никак не могу запустить. Устанавливал Graphviz (версия по Win) от сюда: http://www.graphviz.org/pub/graphviz/stable/windows/graphviz-2.30.1.msi также добавлял путь в переменной PATH к dot.exe . Он запускается в скрипте callgraph_utils.php $cmd = " y:\GraphViz\bin\dot -T".$type; $desсriptorspec подправлял как у Вас в посте. Подскажите куда капнуть что бы заработало? :) Спасибо. Буду благодарен любой помощи.

Веб-разработка крайне сложна под Windows, могу только помочь советом "отказаться от Windows" и жизнь станет проще :-)

Спасибо. В принципе, для обычных стандартных задач при разработке на php практически всегда хватает локального сервера(например Denwer) под Windows. Проблема решилась, правда не совсем то что хотелось, но работает(производится генерация графической диаграммы по данным которые создаются с помощью XHProf). Последняя версия graphviz(Graphviz-2.30.1.msi) под Windows оказалась очевидно не совсем стабильной. Выдавалась ошибка 0xc0150004 при запуске dot.exe. Попытки дать возможно не достающие для запуска dot.exe библиотеки из пакетов .NET Framework, Visual Studio и SP3 ничего не дали. Временно пришлось перейти на более раннюю версию 2.0(http://www.graphviz.org/pub/graphviz/stable/windows/graphviz-2.0.exe). Идею почерпнул из http://superuser.com/questions/539923/graphviz-installation-does-not-work-dll-errors . Может кому-то тоже пригодится.

Не большое дополнение. Подправленная версия php скриптов XHProf http://dev.freshsite.pl/php-extensions/xhprof/file/details/xhprof-html.html Успешно запускает dot.exe (Graphviz-2.30.1) под Windows. Остается только подправить добавленный внутри config.php. Указать свои пути к ERROR_FILE, TMP_DIRECTORY, DOT_BINARY. И все :) данные выводятся, график генерируется.

Оставьте свой комментарий

Markdown