在线上发现某些进程一直在执行,消耗cpu特别的多。需要查看到底是那一段代码的导致的这种情况。在线上时,程序一直在执行,在不能中断程序的情况下,可以通过下面的工具排查信息。
使用格式:
top [-] [d] [p] [q] [c] [C] [S] [s] [n]
参数说明:
top -Hp pid可以查看某个进程的线程信息
-H 显示线程信息,-p指定pid
[root@iz2ze4u1jmuziiojqy873fz]~# top -Hp 22748
top - 14:42:10 up 33 days, 16:29, 1 user, load average: 1.40, 0.59, 0.29
Threads: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.4 us, 0.4 sy, 99.3 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1882088 total, 156740 free, 595876 used, 1129472 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 1104448 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22748 root 25 5 238952 9444 6100 R 98.3 0.5 2:05.30 php
通过top工具可以拿到消耗CPU最高的进程ID信息。
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,可以用来调试C/C++开发的程序,PHP和Swoole是使用C语言开发的,所以可以用GDB来调试PHP+Swoole的程序。
gdb -p 进程ID
gdb php
gdb php core
跟踪正在运行的PHP程序,使用gdb -p 进程ID
使用gdb运行并调试PHP程序,使用gdb php -> run server.php 进行调试
PHP程序发生coredump后使用gdb加载core内存镜像进行调试 gdb php core
如果PATH环境变量中没有php,gdb时需要指定绝对路径,如gdb /usr/local/bin/php
常用命令
zbacktrace是PHP源码包提供的一个gdb自定义指令,功能与bt指令类似,与bt不同的是zbacktrace看到的调用栈是PHP函数调用栈,而不是C函数。
下载php-src,解压后从根目录中找到一个.gdbinit文件,下载地址 注意选择你自己的PHP版本
gdb -p 22748
(gdb) source /path/to/.gdbinit
(gdb) zbacktrace
[0x7ff7e7e13030] (main) /data/www/test/index.php:8
(gdb) zbacktrace
[0x7ff7e7e13030] (main) /data/www/test/index.php:8
(gdb) zbacktrace
[0x7ff7e7e13030] (main) /data/www/test/index.php:8
多执行几次发现是某段代码一直卡住了。查看这段代码即可跟踪解决问题。
cat /data/www/test/index.php
.gdbinit还提供了其他更多指令,可以查看源码了解详细的信息。
strace可以跟踪系统调用的执行情况,在程序发生问题后,可以用strace分析和跟踪问题。 使用方法:
FreeBSD/MacOS下可以使用truss
strace -o /tmp/strace.log -f -p $PID
[root@iz2ze4u1jmuziiojqy873fz]~# strace -p 22748
strace: Process 22748 attached
发现一直卡住了,也可以知道,程序进入了死循环。
参考信息:
https://blog.huoding.com/2015/10/16/474
https://www.php.cn/php-weizijiaocheng-417726.html
https://www.linuxidc.com/Linux/2018-01/150654.htm
https://blog.csdn.net/cs729298/article/details/81906375