背景
在项目中,经常会遇到业务进程不按照自己的预期去执行,比如有时候进程内部突然卡死,但进程本身扔处于存活状态;进程所消耗的cpu和内存很高,但是此时从访问日志和请求量来看并不是很繁忙。当这些问题在线上发生的时候,有些同学就喜欢慌里慌张去重启进程,重启好了,业务恢复后也不去深究原因,导致无法从根本上解决问题。当我们碰到此情况时,一般是先把有问题的机器从线上的流量里隔离出来,然后对该进程进行分析,下面我主要针对以上场景聊聊我们怎么去分析和定位问题。
一个php进程僵死的案例
现象描述:一个后台运行的worker进程,某一天突然发现程序没有按照预期的方向执行,而是假死在那里
分析步骤:
Step 1 运行 strace -p 进程号,跟踪进程的执行状态:
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000) = 0 (Timeout)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
发现进程是阻塞在poll调用上,然后进一步分析,该poll调用对应的业务是啥?
Step 分析对应的文件描述符
lsof -d 6 | grep 30817
php 30817 root 6u IPv4 1020151173 0t0 TCP 10.229.137.42:43402->141.215.141.70:http (ESTABLISHED)
发现是一个http调用卡在那里,然后我们再分析下程序里面调用141.215.141.70这个ip地址的地方,即可定位的有问题代码的位置