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


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

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

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

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

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

Мысли?

Author: Chris Upchurch, 2008-09-11

12 answers

Я использовал Профилирование xdebug недавно в аналогичной ситуации. Он выводит полный отчет о профиле, который можно прочитать со многими распространенными приложениями для профилирования (не могу дать вам список, хотя я просто использовал тот, который поставляется с slackware).

 39
Author: Juan, 2008-09-20 22:12:12

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

 9
Author: MattBelanger, 2008-09-11 14:58:28

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

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

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

 6
Author: Patrick Hogan, 2008-09-11 19:37:26

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

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

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

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

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

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

 3
Author: giltotherescue, 2008-09-15 16:28:45

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

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

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

 2
Author: RobS, 2008-09-11 21:02:48

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

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

 2
Author: Alister Bulman, 2008-09-13 00:24:34

Также Вы можете использовать APD (Расширенный отладчик PHP).

Заставить его работать довольно легко.

$ 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

 2
Author: Fedir RYKHTIK, 2015-02-06 09:57:05

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

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

 1
Author: Brendon-Van-Heyzen, 2008-09-11 20:32:06

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

 1
Author: SeanDowney, 2008-09-12 19:11:09

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

Обозреватель процессов: http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx .

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

 0
Author: Mark, 2008-09-11 03:47:59

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

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

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

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

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

 0
Author: Gary Richardson, 2008-09-11 14:50:03

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

 0
Author: Asuquo12, 2015-05-13 08:38:04