Назад | Перейти на главную страницу

отладка зависшего потока apache / php на рабочем сервере

У меня есть система Linux с apache httpd и PHP, которая загружается с использованием LoadModule php5_module /usr/lib/apache2/modules/libphp5.so.

Я включил модуль mod_status apache, и я вижу конкретный поток, который со вчерашнего дня что-то делает. Я также подтверждаю это, делая ps -axu | grep apache который среди множества потоков дает мне именно этот застрявший поток:

www-data  5636  0.0  0.1 423556 23560 ?      S    XXXXX   0:04 /usr/sbin/apache2 -k start

Обратите внимание, что XXXXX - это что-то вроде января 02, то есть вчера. Кроме того, pid (5636) совпадает с pid застрявшего потока, который я вижу на странице mod_status apache.

У меня вопрос: как сделать дамп потока или что-то подобное, чтобы увидеть, где именно в PHP-коде застряла эта штука? Возможно, он чего-то ждет (ввод-вывод, сеть, база данных), но я не знаю чего.

В мире Java я бы сделал kill -3 pid и получите хороший читаемый дамп потока, который ясно покажет мне, где именно этот конкретный поток застрял. Есть ли подобная техника для php land?

Следующие инструкции ориентированы на Linux:

  • Определите неисправный / застрявший процесс

В вашем случае процесс находится в состоянии S, то есть от man ps:

S прерывистый сон (ожидание завершения события)

Так что да, вероятно, он ожидает завершения какой-либо операции в сети или файловой системе.

  • Отслеживайте системные вызовы и сигналы с помощью strace

Прикрепите strace программу в висящий поток, запустив:

# strace -p 

Это покажет вам в реальном времени действия или, точнее, системные вызовы запущенный программой, например, вы можете увидеть цикл с open() возвращает ошибку, такую ​​как ENOENT это означает, что определенного файла нет.

Ваш ps output указывает, что процесс не потребляет ресурсы ЦП (3-й столбец), поэтому проблема здесь, вероятно, не связана с циклом, а просто с операцией ожидания, такой как заблокированный файл, ожидание сокета или внешнего действия.

  • kill и coredumps

В kill программа, которая используется для отправки определенного сигнала в запущенную программу, далека от java, она вполне может быть использована для отправки сигнала 3 (SIGQUIT), который закроет программу и сгенерирует core файл. Поколение core файл разрешен только при правильном ulimit разрешения имеются, проверьте это с помощью ulimit -c команда. Если это говорит 0, то вы должны изменить его, например, на unlimited:

ulimit -c unlimited

Только после этого следует перезапустить приложение и спровоцировать coredump отправив kill -3.

Вы хотите установить расширение PHP xdebug и включить журнал трассировки. Затем он создаст файл, который будет содержать статистику для каждой выполняемой функции - время, необходимое для выполнения, объем потребляемой памяти, путь к файлу, который содержит эту функцию, и т. Д.

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