我有一个Linux系统与Apache的httpd和PHP使用LoadModule php5_module /usr/lib/apache2/modules/libphp5.so加载。
我已经启用了Apache的mod_status模块,我看到一个特定的线程,从昨天开始就停滞不前。 我也通过做ps -axu | grep apache证实这一点 在许multithreading中,它给了我特定的卡住的线程:
www-data 5636 0.0 0.1 423556 23560 ? S XXXXX 0:04 /usr/sbin/apache2 -k start
请注意,XXXXX就像昨天的Jan02一样。 另外,pid(5636)与我在apache的mod_status页面中看到的卡住线程的pid匹配。
我的问题是:我怎么能做一个线程转储或类似的东西,看看在哪里确切地在PHP代码中卡住这个东西? 也许它正在等待(I / O,networking,数据库),但我不知道是什么。
在java世界中,我会做一个kill -3 pid并获得一个可读的线程转储,清楚地显示出特定线程在哪里被卡住。 有没有类似的技术的PHP土地?
以下指令是以Linux为中心的:
在你的情况下,这个过程是在状态S ,意思是来自man ps :
S可中断睡眠(等待事件完成)
所以是的,它可能正在等待一些networking或文件系统的操作来完成。
strace跟踪系统调用和信号 通过运行将strace程序附加到挂起的线程:
#strace -p
这将实时向您显示操作,更确切地说是程序运行的系统调用 ,例如,您可能会看到open()返回一个错误,如ENOENT意味着某个文件不在那里。
你的ps输出表明这个进程没有占用CPU(第3列),所以这里的问题可能与循环无关,而只是一个等待操作,比如locking文件,等待套接字或者外部动作。
kill和coredumps kill程序,用来发送一个特定的信号到正在运行的程序远非java相关的,它可以很好地发送信号3( SIGQUIT ),它将closures程序并生成一个core文件。 core文件的生成只有在具有正确的ulimit权限时才被允许,请使用ulimit -c命令进行检查。 如果它说0 ,那么你应该修改它,例如, unlimited :
ulimit -c无限制
只有这样你才能重新启动应用程序并通过发送kill -3激发一个coredump 。
您想要安装PHP xdebug扩展并启用跟踪日志 。 然后它将创build一个文件,该文件将具有每个执行的function的统计信息 – 完成所花费的时间,消耗的内存量,包含该function的文件path等。
这些数据将帮助您确定哪些function需要修复,但请注意,完整跟踪日志的大小会非常快速地增长,您可能只想跟踪部分应用程序(也在上面的指南中进行了描述)。