У меня давно выполняется задание cron CLI, написанное на PHP. По прошествии непоследовательного периода времени сценарий перестает записывать выходные данные в свой файл журнала, указывая на то, что он прекратил выполнение.
Однако сценарий все еще выполняется, что подтверждено с помощью ps aux
.
скрипт не генерирует никаких исключений и не выводит никаких ошибок. Когда он останавливается, кажется, что он больше не потребляет ЦП.
Память не является проблемой - сценарий использует ini_set («memory_limit», «1G»);
и, кажется, зависает, когда сценарий использует только около 73 МБ. Сценарий выполняется на специализированном компьютере (8 ГБ ОЗУ, 8 ЦП, PHP 5.6.25) с большим количеством свободной памяти, дискового пространства, inodes, / tmp, доступного ЦП и т. Д.
Использование журнала трассировки функции xdebug , Я вижу, что скрипт просто останавливается на ничем не примечательном вызове функции. «Обычное» выполнение xdebug записывает что-то вроде TRACE END [2019-03-26 13:02:55]
в конец файла журнала и затем завершается. Однако, когда сценарий зависает, эта строка не появляется, и сценарий не завершается. Например:
«Застрявший» журнал функции xdebug, Пример A:
1481.7659 73187512 -> in_array() /home/xyz/inc/util/email.inc:156
1481.7659 73187056 -> strpos() /home/xyz/inc/util/email.inc:170
1481.7659 73187208 -> mail() /home/xyz/inc/util/email.inc:181
«Застревание» не всегда происходит в одной и той же функции.
«Застрявший» журнал функции xdebug, Пример B:
1422.5710 73306784 -> strrpos() /home/xyz/inc/util/external-common.inc:106
1422.5710 73306840 -> substr() /home/xyz/inc/util/external-common.inc:108
1422.5710 73307008 -> shell_exec() /home/xyz/inc/util/external-common.inc:112
«Нормальный» "xdebug function log:
55190.4859 35183552 -> WP_Object_Cache->__destruct() /home/xyz/public_html/wp/wp-includes/cache.php:0
55190.8278 34830224 -> wpdb->__destruct() /home/xyz/public_html/wp/wp-includes/wp-db.php:0
55193.1823 8672
TRACE END [2019-03-26 13:02:55]
Это может быть простым совпадением, но я вижу единственную общую тему, которая может иметь какое-то отношение к C's popen ()
- it (или родственник), похоже, используется как PHP mail ()
, так и shell_exec ()
. Я не думаю, что у меня слишком много открытых процессов (недавно проверено; у меня нет команды, которую я использовал). Сценарий выполняет не более 5 shell_exec ()
вызовов в секунду, и выполнение каждого вызова занимает менее секунды. (К тому же, если бы это было проблемой, разве я не получил бы какую-то ошибку вместо этого «зависания»?)
Что может происходить?
Что мне делать дальше?
Проследите его дальше, до того, какая функция уровня пользователя или ядра занимает много времени.
Используйте ltrace
для отслеживания системных вызовов и вызовов библиотеки C. Получите представление о том, что он делает.
Чтобы отследить теорию исполнителей и программ, попробуйте наблюдать за исполнителями с помощью execsnoop
.
В том же наборе сценариев проверьте популярный мем, который это всегда DNS с gethostlatency
.
Оба они являются eBPF и поэтому не будут доступны с ядром CentOS. Однако вы можете найти или написать их варианты, реализованные в доступных инструментах, таких как ftrace.