Узнайте, где замедляется ваш PHP-код (проблема с производительностью)

Вот мой первый вопрос в SO.

У меня есть внутреннее приложение для моей компании, о котором я недавно просил поддерживать. Приложения построены на PHP и довольно хорошо закодированы (OO, DB Abstraction, Smarty) ничего WTF-ish.

Проблема в том, что приложения очень медленные .

Как мне узнать, что замедляет приложение? Я оптимизировал код, чтобы сделать очень мало запросов к БД, поэтому я знаю, что это код PHP, который требуется для выполнения. Мне нужно получить некоторые инструменты, которые могут помочь мне в этом, и вам нужно разработать стратегию проверки моего кода.

Я могу самостоятельно выполнять проверку / стратегию, но мне нужно больше инструментов PHP, чтобы выяснить, где работает мое приложение.

Мысли?

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

Как отметил Хуан, xDebug отлично. Если вы работаете в Windows, WinCacheGrind позволит вам просматривать отчеты.

Посмотрите эту презентацию Расмуса Лердорфа (создателя PHP). Он приводит некоторые хорошие примеры тестирования скорости PHP и того, что нужно искать, а также некоторых внутренних компонентов, которые могут замедлить работу. XDebug – это один из инструментов, который он использует. Он также дает очень четкое представление о том, какие затраты на производительность вы вносите в рамки.

Видео: http://www.archive.org/details/simple_is_hard

Слайды (так как их невозможно увидеть на видео): http://talks.php.net/show/drupal08/1

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

Во-первых, как вы обслуживаете PHP? Пробовали ли вы базовую оптимизацию Apache или IIS? Является ли сервер занятым обработкой других видов запросов? Вы использовали ускоритель PHP-кода ? Один из способов проверить, является ли сервер вашим узким местом, – попробовать запустить приложение на другом сервере.

Во-вторых, медленное выполнение всего приложения, или это влияет только на определенные страницы? Это может дать вам представление о том, где начать анализ производительности. Если все приложение работает медленно, проблема более вероятна в базовом сервере / платформе или глобальном SQL-запросе, который является частью каждого запроса (например, аутентификация пользователей).

В-третьих, вы упомянули о минимизации числа SQL-запросов, но как насчет оптимизации существующих запросов? Если вы используете MySQL, пользуетесь ли вы преимуществами каждой системы хранения? Вы запускаете EXPLAIN в своих наиболее важных запросах, чтобы убедиться, что они правильно проиндексированы? Это важно для запросов, обращающихся к большим таблицам; чем больше набор данных, тем больше вы заметите эффекты плохой индексации. К счастью, есть много статей, таких как этот, которые объясняют, как использовать EXPLAIN.

В-четвертых, распространенная ошибка заключается в том, чтобы предположить, что ваш сервер базы данных будет автоматически использовать все ресурсы, доступные для системы. Необходимо убедиться, что вы явно выделили достаточные ресурсы для своего приложения базы данных. Например, в MySQL вы хотите добавить пользовательские настройки (в файл my.cnf) для таких вещей, как буфер ключей, размер таблицы тем, параллельность потоков, размер пула буферов innodb и т. Д.

Если вы дважды проверили все вышеперечисленное и по-прежнему не можете найти узкое место, возможно, поможет определенный профилировщик кода, такой как Xdebug. Лично я предпочитаю профайлер Zend Studio, но это может быть не лучший вариант, если вы уже не воспользовались остальной частью стека платформы Zend. Однако, по моему опыту, очень редко, что сам PHP является основной причиной медленной производительности. Часто профайлер кода может помочь вам определить с большей точностью, какие запросы БД виноваты.

phpED ( http://www.nusphere.com/products/phped.htm ) также предлагает отличную отладку и профилирование, а также возможность добавлять часы, точки останова и т. д. в PHP-код. Интегрированный профайлер напрямую предлагает временную разбивку каждого вызова функции и метода класса из среды IDE. Плагины браузера также позволяют быстро интегрироваться с Firefox или IE (т. Е. Посещать медленный URL-адрес с браузером, а затем щелкнуть по кнопке для профиля или отладки).

Было очень полезно указать, где приложение работает медленно, чтобы сконцентрировать большинство усилий по кодированию; и это позволяет избежать траты времени, оптимизируя уже быстрый код. Попробовав Zend и Eclipse, я теперь был продан с легкостью использования phpED.

Имейте в виду, что Xdebug и phpED (с DBG) потребуют дополнительного модуля PHP, установленного при отладке на веб-сервере. phpED также предлагает (не проверяемый мной) вариант локальной отладки.

Профиль Xdebug – это, безусловно, путь. Еще один совет – WincacheGrind хорош, но не обновлялся в последнее время. http://code.google.com/p/webgrind/ – в браузере может быть простой и быстрой альтернативой.

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

Также вы можете использовать APD (Advanced PHP Debugger).

Легко заставить его работать.

$ php apd-test.php $ pprofp -l pprof.SOME_PID Trace for /Users/martin/develop/php/apd-test/apd-test.php Total Elapsed Time = 0.12 Total System Time = 0.01 Total User Time = 0.07 Real User System secs/ cumm %Time (excl/cumm) (excl/cumm) (excl/cumm) Calls call s/call Memory Usage Name -------------------------------------------------------------------------------------- 71.3 0.06 0.06 0.05 0.05 0.01 0.01 10000 0.0000 0.0000 0 in_array 27.3 0.02 0.09 0.02 0.07 0.00 0.01 10000 0.0000 0.0000 0 my_test_function 1.5 0.03 0.03 0.00 0.00 0.00 0.00 1 0.0000 0.0000 0 apd_set_pprof_trace 0.0 0.00 0.12 0.00 0.07 0.00 0.01 1 0.0000 0.0000 0 main 

Существует хороший учебник по компиляции APD и профилированию с ним: http://martinsikora.com/compiling-apd-for-php-54

если его большая база кода попробует apc, если вы еще этого не сделали.

http://pecl.php.net/package/APC

вы также можете попробовать использовать функцию register_tick_function в php. который сообщает php о вызове определенной функции с помощью кода. Затем вы можете отслеживать, какая функция в данный момент работает, и количество времени между вызовами. то вы могли бы видеть, что занимает больше всего времени. http://www.php.net/register_tick_function

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

Проводник процессов: http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx .

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

Я использую комбинацию тестов PEAR и log4php .

В верхней части скриптов, которые я хочу профилировать, я создаю объект, который обтекает объект Benchmark_Timer . В течение всего кода я добавляю в $object->setMarker("name"); , особенно в отношении подозрительного кода.

Класс wrapper имеет метод destroy, который берет информацию о регистрации и записывает ее в log4php. Обычно я отправляю это в syslog (многие серверы, агрегаты в один файл журнала на одном сервере).

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

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

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