一般情况下,PHP-CGI只在用户访问的时候会占用CPU资源,如果服务器上的PHP-CGI进程占用了非常多的CPU,但是访问流量却非常少。这显然是一个不正常的现象

1.使用  top   找出CPU最高的进程pid

2 ll /proc/PID/fd      //通过PID找到哪个文件操作的进程,进而知道问题所在

3 strace -p PID(进程数) 来跟踪进程

Linux分析进程占用内存最高和占用CPU最高

这里只显示最高的前5个,如果想显示更多的话,可以自己修改:

查看占用内存最高的5个进程

ps aux | sort -k4nr | head -n 5

查看占用cpu最高的5个进程

ps aux | sort -k3nr | head -n 5

查看是否是硬件问题

  方式:top  命令

  主要查看:load average(平均负载),这是一个4核8G内存的服务器

  1分钟平均负载:2.32;

  5分钟平均负载:2.18;

  15分钟平均负载:3.95;

  load average  中3个数的含义,如果是1核cpu,那么不能超过1,4核那么就不能超过4,15分钟可以代表长期,5分钟代表中期,1分钟代表短期,所以先看15分钟

  大神详解load average

  可以说它现在的平均负载接近了它的cpu总核数:4;需要考虑服务器配置升级!


php-fpm.conf 文件一般位于 /www/server/php/70/etc 目录下,注意 70 是php的版本号,需要根据你的php版本变更。


1  ---- 此文章是单个PHP进程使用CPU过高

公司服务器CPU占用过高,报警了,第一反应是登录服务器, top 命令查看当前进程,再输入 P 按cpu排序 :

      

果然看到有多个php-fmp进程占用cpu过高,都达到100%了

于是打算监听一下进程,看看在执行什么操作,使用 strace 命令:     

#监听进程    strace -o /tmp/output.txt -T -tt -F -e trace=all -p 7757
#查看log     tail -f /tmp/output.txt


结果还没看出来什么,cpu占用率已经下来了,那几个进程已经结束了。最后通过 php慢日志 发现了端倪。

php慢日志开启条件,需要在 php-fpm.conf 配置如下:

request_slowlog_timeout = 1      #脚本超时秒数,超过1稍都算慢了
slowlog = /var/log/php.log.slow  #记录慢日志路径

查看近1000条php慢日志:

tail -n 1000 /var/log/php.log.slow
经查找发现了罪魁祸首,是前同事留下的一个大递归操作有问题:      

然后优化代码就可以了。

这种个别php-fpm进程cpu占用过高,基本上是由于程序本身存在问题(如程序无限循环逻辑),优化程序后如果还得不到解决,那就如网上所说需要考虑 php-fpm.conf 里面的一些配置参数了,以及升级服务器。

此文:https://blog.csdn.net/msllws/article/details/107090542


 

2---此文章是单个PHP进程使用CPU过高

当我打开宝塔面板的时候,惊呆了,
服务器 cup使用率100%,负载状态100%,瞬间从一万米高空坠下,周身气温降到零下。

   看到这种情况,我只能努力的平复面临崩溃的心态,右手抚额,由上而下,滑过鼻尖的时候深吸一口气,
假装淡定的 一顿shell操作,查看源头(其实只会一个top \:手动狗头),随之百度一番,过程万分艰辛,请谨慎食用。
在这里插入图片描述
step1:top大法
[root@xxxxxxxxxxxxxxxx ~]# top
在这里插入图片描述

记下进程号
step2:找到罪魁祸首
[root@xxxxxxxxxxxxxxxx ~]# ll /proc/3295/fd

在这里插入图片描述
显示socket最高

   至此,分析原因,socket最高,那就应该是跟服务器上的webserver有关,因为客服项目中用到了workerman,当时部署的时候我还启动过,问题应该在这里,
接着查看php进程在做啥,为啥会占用如此之高的cpu

step3:分析犯罪心理
[root@xxxxxxxxxxxxxxxx ~]# strace -p 3295

在这里插入图片描述
显示 pcntl_wait() 函数已被禁用,原因找到了(内心狂喜,oh~~~)

step4:物理治疗(开开心心的去删除禁用列表的该函数)

在这里插入图片描述
   重启php,让后观察cpu状态,然鹅~~~~ GG,等了几分钟之后,依旧没有丝毫下降的趋势。
我心里又慌得一批,难道是我找错方向了?难道是我技术太菜了?难道是我不配做写代码? 
   灵魂三连问之后,想到php的配置虽然修改了,但是服务器上运行的web服务里面加载的还是未改动之前的配置,
果断重启所有web服务,开启重启大法(如果这样还不行,那就剩下最后的大招了,重启服务器,哈哈哈哈~~~)
tep5:查看战果

重启workerman,运行几分钟任然正常,perfect!
原文链接:https://blog.csdn.net/qq_39376990/article/details/109573083


3.  PHP-fpm(php-cgi)的进程数过多

     首先使用 free -m 指令查看当前服务器执行状况:

  

  可以看到当前我这设备的内存消耗不多,也能看到我是2G内存

     如果我们发现php-cgi进程数量过多时,虽然单个php-cgi占用内存并不算太大,但是大量的php-cgi进程就有点恐怖了。几乎占尽了全部内存(可自动累加其使用的内存率),因此 我们可通过设置php-cgi数量来缓解内存消耗过高的问题,

     php-cgi由php-fpm管理,因此可以断定,是由于php-fpm配置文件中的max_children参数配置不当,才导致打开过多的php-cgi进程。所以要适当调整下max_children的设置。

  然后再用  top  命令 m 参数  查看内存情况

  再使用:ps auxw|head -1;ps auxw|sort -rn -k4|head -40      查看消耗内存最多的前40个进程

  查看通过命令查看服务器上一共开了多少的 php-cgi 进程:ps -fe |grep "php-fpm"|grep "pool"|wc -l

  查看已经有多少个php-cgi进程用来处理tcp请求:netstat -anp|grep "php-fpm"|grep "tcp"|grep "pool"|wc -l

  设置PHP-FPM的进程数:vi /www/server/php/70/etc/php-fpm.conf(根据实际情况变化)找到 pm.max_children 字段,设置一个合理的值,比之前的小

  pm.max_spare_servers : 该值表示保证空闲进程数最大值,如果空闲进程大于此值,此进行清理 pm.min_spare_servers : 保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程;

  这两个值均不能不能大于 pm.max_children 值,通常设置 pm.max_spare_servers 值为 pm.max_children 值的60%-80%。

  正常情况下,一个php--fpm占用内存20~30M 

       Nginx使用的php-fpm的三种进程管理方式及优化 pm.start_servers pm.max_children参数说明


4.  PHP-fpm(php-cgi)的进程数过多

发现问题以后,首先使用 free -m 指令查看当前服务器执行状况:

可以看到我的服务器内存是2G的,但是目前可用内存只剩下70M,内存使用率高达92%,很有可能是内存使用率过高导致数据库服务挂断。

继续看详细情况,使用 top 指令:

然后再看指令输出结果中详细列出的进程情况,重点关注第10列内存使用占比:

发现CPU使用率不算高,也排除了CPU的问题,另外可以看到数据库服务占用15.2%的内存,内存使用过高时将会挤掉数据库进程(占用内存最高的进程),导致服务挂断,所以我们需要查看详细内存使用情况,是哪些进程耗费了这么多的内存呢?

使用指令:

1

ps auxw|head -1;ps auxw|sort -rn -k4|head -40

查看消耗内存最多的前40个进程:

查看第四列内存使用占比,发现除了mysql数据库服务之外,php-fpm服务池开启了太多子进程,占用超过大半内存,问题找到了,我们开始解决问题:设置控制php-fpm进程池进程数量。

解决问题

通过各种搜索手段,发现可以通过配置 pm.max_children 属性,控制php-fpm子进程数量,首先,打开php-fpm配置文件,执行指令:

1

vi /etc/php-fpm.d/www.conf

找到 pm.max_children 字段,发现其值过大:

如图, pm.max_children 值为50,每一个进程占用1%-2.5%的内存,加起来就耗费大半内存了,所以我们需要将其值调小,博主这里将其设置为25,同时,检查以下两个属性:

pm.max_spare_servers : 该值表示保证空闲进程数最大值,如果空闲进程大于此值,此进行清理 pm.min_spare_servers : 保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程;

这两个值均不能不能大于 pm.max_children 值,通常设置 pm.max_spare_servers 值为 pm.max_children 值的60%-80%。

最后,重启php-fpm

1

systemctl restart php-fpm

再次查看内存使用情况, 使用内存降低很多:

之后经过多次观察内存使用情况,发现此次改进后,服务器内存资源消耗得到很大缓解。

ps:查看php-fpm开启的进程数以及每个进程的内存限制

1.通过命令查看服务器上一共开了多少的 php-cgi 进程

1

ps -fe |grep "php-fpm"|grep "pool"|wc -l

2.查看已经有多少个php-cgi进程用来处理tcp请求

1

netstat -anp|grep "php-fpm"|grep "tcp"|grep "pool"|wc -l

3.linux+nginx+php环境中,每个php-fpm进程的内存限制

设置方法:

编辑php-fpm.conf配置文件内的属性php_admin_value[memory_limit] = 128M( 后边的数字可以随便更改:32M,64M,128M,256M,512M,这个设置可根据你的服务器内存大小和你的需求来写,修改后要加载一下php-fpm服务。


5.  PHP-fpm(php-cgi)的进程数过多

机房一台服务器运行一段时间后,突然发现系统资源即将被耗尽!

1)top命令查看一下系统的cpu ram swap的使用情况

 

由上图分析,可以看出 1--共有602个进程,但其中有601个进程休眠了。 这就有点不对劲,这台服务器的内核进程也就80个左右,加上memcached, nginx, mysqld,也不会超出90个,除了这些,剩下的只有php-fpm管理的php-cgi了。 2--CPU显示,CPU压力并不大,可以说没有压力。 3--内存使用概要,发现4G的内存,消耗得所剩余无几(free+buffers),95%以上的内存都已分配;交互空间使用情况,暂时不去关心。指令top还列出了占用资源最多的进程,运行时间最久(Time+)的mysqld(约2小时)占用资源并不是最多。 4--再看php-cgi,单个php-cgi占用的内存也不算多。 所以,可以大胆地猜想:服务器内存资源比较紧张,并没有被某个进程占用大量内存,有可能被某些挂起的进程占着内存没有释放。通过free进一步监控内存使用情况,验证我们的想法。

2)查看ram的使用情况

 

先来看Mem统计信息,total表示物理内存总量,约4G。used,表示已分配内存,分配了并不表示使用了,包括(buffer&cached)。free指未分配的内存,buffers与cached表示分配了但还没有被使用的内存。第二行(buffers/cache)的,used表示真正被使用了内存,由第一行的(used-buffer-cached)得到,free则表示还没有被使用的内存,由第一行的(free+buffer+cached)得到。Swap行则表示内存交换使用情况,少量的(不频繁地)swpd,是不会影响服务器性能的,因为系统需要将V类型的内存页面交换出去或者调整了buffer与cached的大小。但是频繁地swpd,则有可能意味着服务器物理内存不足,小于指定的swap额定值,需要换出内存页。

查看free结果的时候,主要查看第二行。一眼就能看出4G的内存,其中有3898M内存被用了,还有49M内存没有,都快用完了。 这也证实了第一步的猜想,内存被用完! 这里,可以进一步猜想,内存空间严重不足的情况下,进程会被blocked,系统会不断地将不用的数据换出so,将要用的数据读入si。 下面通过vmstat进一步验证这个猜想。

3)vmstat监控内存的使用情况(执行命令:vmstat)

 

作为对内存监控,比较重要的还是swpd、free、si、so。 一般系统不繁忙的状态下,可以看到swpd,so的值不会持续很高,经常为0。 这里看到swpd值为1.5G,以及free值很小,再一次表明物理内存不足。其中si报告了每秒从swap区移入到物理内存的内存总量,so报告了每秒从物理内存移出到swap区的内存总量。 当然,si有时较大,并不要过份的焦虑,经常碰到一个程序需要较大内存来读写媒体文件时,si值就会变大。反倒是so,它通常是一个内存紧缺的一个信号,如果长时间这个值一直保持较大的话,则很有可能内存不够,小额波动,可以不用理会。接下来,可以通过ps找出消耗内存的元凶。

4)ps找出消耗内存的元凶(执行命令:ps -A -sort -rss -o comm,pmem,pcpu|uniq -c|head -15)

 

指令ps比较常用,也比较简单。从上面报告结果中可以一眼看到php-cgi这个进程。虽然单个php-cgi占用内存并不算太大,但是503个php-cgi进程,就有点恐怖了。几乎占尽了全部内存(503*0.3%)。php-cgi由php-fpm管理,因此可以断定,是由于php-fpm配置文件php.ini中的max_children参数配置不当,才导致打开过多的php-cgi进程。所以要适当调整下max_children的设置。

Logo

华为云1024程序员节送福利,参与活动赢单人4000元礼包,更有热门技术干货免费学习

更多推荐