Странным образом зависают PHP скрипты (suPHP)

12
Romka_Kharkov
На сайте с 08.04.2009
Offline
485
5135

День добрый,

Давненько не писал сюда, всех приветствую :)

#1


PHP 5.3.29 (cli) (built: Nov 29 2014 16:29:49)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies
with the ionCube PHP Loader v4.6.1, Copyright (c) 2002-2014, by ionCube Ltd., and
with Zend Guard Loader v3.3, Copyright (c) 1998-2010, by Zend Technologies
with Suhosin v0.9.33, Copyright (c) 2007-2012, by SektionEins GmbH

#2


Server version: Apache/2.2.29 (Unix)
Server built: Nov 29 2014 16:24:44
Cpanel::Easy::Apache v3.26.10 rev9999
Server's Module Magic Number: 20051115:36
Server loaded: APR 1.5.1, APR-Util 1.5.4
Compiled using: APR 1.5.1, APR-Util 1.5.4
Architecture: 64-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses disabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=128
-D HTTPD_ROOT="/usr/local/apache"
-D SUEXEC_BIN="/usr/local/apache/bin/suexec"
-D DEFAULT_PIDLOG="logs/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="logs/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"

С завидной регулярностью на сервере плодятся процессы типа таких:


$user 22249 0.0 0.0 189520 11356 ? S Jul14 0:00 /usr/bin/php /home/$user/public_html/video.php
$user 22268 0.0 0.0 189520 11360 ? S Jul14 0:00 /usr/bin/php /home/$user/public_html/video.php
$user 22376 0.0 0.0 189520 11360 ? S Jul14 0:00 /usr/bin/php /home/$user/public_html/video.php
$user 22446 0.0 0.0 189520 11356 ? S Jul14 0:00 /usr/bin/php /home/$user/public_html/video.php

При этом если обратить на время запуска скрипта, оно - Jul14, а данный ps снят .... аж 20го числа, т.е скрипт висит в непонятном состоянии целых 6 дней.... При этом стоит обратить внимание что max_execution_time в PHP установлен в адекватное значение 30 sec....

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

1. Скрипт запустился и пишет лог в getmypid().txt.

2. Выполняется функция #1

3. Выполняется функция #2

4. Выполняется функция N

5. Последним действием происходит unlink() на тот самый getmypid().txt

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

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

Есть еще подозрение связанное с конектами.... в процессе работы сценария он производит обращения к удаленным ресурсам, при этом как мы понимаем по разным причинам они могут быть недоступны и.т.п но в хедерах курлу передается timeout, а так же должны быть какие-то адекватные таймауты и в самой системе на тему установления соединения..... да и в общем-то совсем не ясно почему в этом случае игнорируется max_execution_time..... Если процесс как мы видим в состоянии Sleep, то как бы его должно прибить, на сколько я понимаю max_execution_time прибьет даже процесс который в состоянии Runing... а не то что sleep .... собственно какое-то WTF!!! Памагите! :)

Возможно у кого-то есть какие-то соображения на эту тему? Может кто-то сталкивался с чем-то подобным , может не совсем удачная версия PHP ?

Есть около 15.000 ipv4 !!! (http://onyx.net.ua/price.php#ipv4) Качественный хостинг с 2005 года - лучшее клиентам! (http://onyx.net.ua/)
edogs software
На сайте с 15.12.2005
Offline
743
#1

а) max_execution_time это условно-физическое время которое скрипт выполняет непосредственно работу, а не внешнее время его выполнения. В него не входят вызовы sleep(), задержки получения файлов по сети типа file_get_contents(), задержки получения данных из базы mysqli_query, чтение файлов fread, вызовы всяких системных команд типа ffmpeg и прочее. В общем на max_execution_time как на убийцу полагаться нельзя.

http://php.net/manual/ru/function.set-time-limit.php

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

б) Если используется register_shutdown_function или ob_start , то эти функции которые были назначены к вызову через них - будут выполнены не то что "помимо" max_execution_time , но даже как раз в ситуации когда "время жизни" скрипта истекло и он как раз по этой причине был "какбэзавершен".

Простое решение - прибивать процесс пхп "внешне" - выставьте лимиты в апаче (Timeout директива), это кстати в любом случае невредно бы сделать. Неправильно, когда скрипты висят сутками.

Умное решение - разберитесь что именно в скрипте висит. До куда он не дошел - Вы выяснили, но теперь выясните на чем он зависает.

Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход.
Romka_Kharkov
На сайте с 08.04.2009
Offline
485
#2

edogs,


# cat /etc/httpd/conf/httpd.conf|grep -i timeo
Timeout 150
KeepAliveTimeout 5
SSLSessionCacheTimeout 300

Таймаут установлен в 150. Если говорить про сам апач....

Насчет max_execution - почитал, перечитал и таки вы правы.

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

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

Еще гипотезы?

edogs software
На сайте с 15.12.2005
Offline
743
#3

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

Если у Вас multi_curl, то он безбожно глючит почти в каждой из версий php так или иначе, использовать curl можно только однопоточно.

Кроме того, в курле куча таймаутов, посмотрите - может какой-то не выставили?

И в идеале скармливать курлу не доменное имя, а IP-шник, с dns в некоторых случаях он как-то неадекватно работает, когда много обращений идет - вдруг перестает понимать куда стучать или повисает (опять же, не на всех версиях php).

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

Если уверены что скрипт доходит до конца - попробуйте как раз обратиться к register_shutdown_function или ob_start - она сработает после завершения скрипта и возможно даст какую-то информацию. Только учтите, что к моменту начала ее работы - окружение скрипта (текущая директория в частности, права владельца) может оказаться уже не тем, что при запуске, поэтому заранее озаботьтесь абсолютными путями для логов и правами в файлах куда их писать.

Z
На сайте с 06.09.2012
Offline
129
#4

Записать strace/ktrace можно?

Или может strace -f -p <pid> что-то и так показывает?

Черный список врунов и обманщиков: ua-hosting.company, riaas.ru, takewyn.ru, yahoster/cadedic, Andreylab
Romka_Kharkov
На сайте с 08.04.2009
Offline
485
#5
edogs:
Попросите админов сервера разобраться в чем проблема с таймаутом, ну или может сюда в топик заглянут. Это уже не программистская проблема - почему процессы висят дольше чем положено, так что не Вы должны разбираться, а хостер.

Немного внимания и станет понятно , что я и есть хостер.

edogs:

Если у Вас multi_curl, то он безбожно глючит почти в каждой из версий php так или иначе, использовать curl можно только однопоточно.
Кроме того, в курле куча таймаутов, посмотрите - может какой-то не выставили?
И в идеале скармливать курлу не доменное имя, а IP-шник, с dns в некоторых случаях он как-то неадекватно работает, когда много обращений идет - вдруг перестает понимать куда стучать или повисает (опять же, не на всех версиях php).

Таймауты выставлены в принципе все которые известны. Не совсем понимаю, чем может быть чревато "подвисание" курла.... с одной стороны если включить сюда логику про max_execution_time, то становится ясно, что пока курл "задумался" этот счетчик типа не щелкает, однако если не указывать курлу таймауты... по какой же причине не срабатывает таймаут веб сервера.... который по идее должен порвать с клиентом связь и как следствие убить дочерние процессы в виде php .... ? Так же не понимаю, должны же быть какие-то системные таймауты, которые рано или поздно за 6 суток дадут понять курлу что отрезолвить имя не удалось или подключение не удалось в принципе.....

edogs:

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

А кто вам сказал что какие-то файлы качаются? Пожалуйста, читайте внимательно, что я пишу.

edogs:

Если уверены что скрипт доходит до конца - попробуйте как раз обратиться к register_shutdown_function или ob_start - она сработает после завершения скрипта и возможно даст какую-то информацию. Только учтите, что к моменту начала ее работы - окружение скрипта (текущая директория в частности, права владельца) может оказаться уже не тем, что при запуске, поэтому заранее озаботьтесь абсолютными путями для логов и правами в файлах куда их писать.

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

---------- Добавлено 21.07.2015 в 02:25 ----------

zzzit:
Записать strace/ktrace можно?
Или может strace -f -p <pid> что-то и так показывает?

Есть рут, записать можно в принципе все, на сейчас зависших процессов нет, как только появятся , попробую strace натравить, однако в случае php .... че он там покажет то... ? 🙄

Z
На сайте с 06.09.2012
Offline
129
#6
Romka_Kharkov:
должны же быть какие-то системные таймауты, которые рано или поздно за 6 суток дадут понять курлу что отрезолвить имя не удалось

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

Romka_Kharkov:
Есть рут, записать можно в принципе все, на сейчас зависших процессов нет, как только появятся , попробую strace натравить, однако в случае php .... че он там покажет то... ? 🙄

Покажет точно на чем виснет, чего ждет. Не раз мне помогал на чужих скриптах.

dkameleon
На сайте с 09.12.2005
Offline
386
#7
Romka_Kharkov:
Возможно у кого-то есть какие-то соображения на эту тему? Может кто-то сталкивался с чем-то подобным , может не совсем удачная версия PHP ?

а всякие register_shutdown_function прогер не использует случаем?

Дизайн интерьера (http://balabukha.com/)
UF
На сайте с 25.12.2011
Offline
28
#8

Скорей всего набор функций кодера жрет чего-то слишком много, нужно в код глядеть, если есть похожие функции, то переадресовать их по указателям и вызывать когда нужно, как ведет себя ОЗУ при выполнении набора функций?

N
На сайте с 06.05.2007
Offline
419
#9

Ну покажите что-ли gdb -p <pid> , а потом вывод bt.

bt - это backtrace, список системных вызовов.

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

Кнопка вызова админа ()
Romka_Kharkov
На сайте с 08.04.2009
Offline
485
#10
dkameleon:
а всякие register_shutdown_function прогер не использует случаем?

Нет, не используются.

---------- Добавлено 21.07.2015 в 12:14 ----------

UnFeeLing:
Скорей всего набор функций кодера жрет чего-то слишком много, нужно в код глядеть, если есть похожие функции, то переадресовать их по указателям и вызывать когда нужно, как ведет себя ОЗУ при выполнении набора функций?

В том то и фишка, единственное, что может ждать это CURL.... все остальное это штатный набор минимальных функций типа preg_replace.... и.т.п... Изучаем пока поведение курла.

---------- Добавлено 21.07.2015 в 12:15 ----------

netwind:
Ну покажите что-ли gdb -p <pid> , а потом вывод bt.
bt - это backtrace, список системных вызовов.
Конечно, не ахти какой удобный способ при отсутствии связи с исходниками и отладочной информации, но там будут называния некоторых функций и можно делать предположения.

За последние сутки пока висяков не нашлось, как только появятся , буду их трейсить и gdb тоже натравлю. tnx.

Регулярность зависания как таковая отсутствует, я даже предполагаю, что зависание может образовываться в совокупности с нагрузками на сервере но подтвердить это пока не удается, графики нагрузки говорят о том, что её нет... ))))

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий