是什么原因导致我们的 PHP 脚本停滞?

是什么原因导致我们的 PHP 脚本停滞?

我有一个用 PHP 编写的长期运行的 CLI cron 作业。在一段不一致的时间段后,脚本停止将输出写入其日志文件,表明它已停止执行。

然而,脚本仍然在运行,已确认ps aux

脚本没有抛出任何异常或输出任何错误。当它停滞时,它似乎不会再消耗任何 CPU。

内存不是问题 - 脚本使用内存ini_set("memory_limit", "1G");,当脚本仅使用约 73 MB 时似乎会冻结。脚本在功能强大的专用机器(8 GB RAM、8 个 CPU、PHP 5.6.25)上运行,具有充足的可用内存、磁盘空间、inode、/tmp 空间、可用 CPU 等。

使用 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 功能日志:

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 有关popen()- 它(或相关)似乎被 PHP 所使用mail()shell_exec()。我认为我没有打开太多进程(最近验证过;手头没有我使用的命令)。该脚本shell_exec()每秒最多只执行 5 次调用,每次调用执行时间不到一秒钟。(另外,如果这是一个问题,我会不会收到某种错误而不是这种“停滞”行为?)

会发生什么事?

我下一步该怎么做?

答案1

进一步跟踪,直到任何用户或内核级别的函数花费很长时间。

用于ltrace观察系统调用和 C 库调用。了解它正在做什么。

为了追踪执行程序的理论,尝试观察高管execsnoop

在同一个脚本集合中,检查始终使用 DNS 的流行 meme gethostlatency

这两个都是 eBPF,因此在 CentOS 内核中不可用。但是,您可能会在可用工具(如 ftrace)中找到或编写它们的变体。

相关内容