一、问题描述 {#一、问题描述}
过了个周末发现博客网站变得很慢,发布文章特别迟钝。经过登录服务器查看资源使用情况发现是php-fpm进程将内存全部占用,才导致了变慢的情况。通过查找了解了其中的部分原理:
LNMP架构中PHP是运行在FastCGI模式下,按照官方的说法,php-cgi会在每个请求结束的时候会回收脚本使用的全部内存,但是并不会释放给操作系统,而是继续持有以应对下一次PHP请求。而php-fpm是FastCGI进程管理器,用于控制php的内存和进程等。
所以,解决的办法就是通过php-fpm优化总的进程数和单个进程占用的内存,从而解决php-fpm进程占用内存大和不释放内存的问题。
二、分析思路 {#二、分析思路}
查看服务器内存
[root@dameng linuxscript]# free -m
total used free shared buff/cache available
Mem: 3736 3469 114 1 151 72
Swap: 4095 2131 1964
占用CPU最多的10个进程
[root@dameng linuxscript]# ps aux|head -1;ps aux|sort -rn -k +3|head
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
www 87009 0.0 1.9 424552 73072 ? S Dec13 1:30 php-fpm: pool www
www 77548 0.0 0.1 97456 4200 ? S Dec12 0:11 nginx: worker process
www 77547 0.0 0.1 97460 5780 ? S Dec12 0:11 nginx: worker process
www 7384 0.0 2.4 436428 91832 ? S Dec09 6:26 php-fpm: pool www
www 73344 0.0 2.4 428988 93996 ? S Dec12 3:25 php-fpm: pool www
www 6787 0.0 2.4 441144 92476 ? S Dec09 6:29 php-fpm: pool www
www 6785 0.0 2.4 446040 92264 ? S Dec09 6:30 php-fpm: pool www
www 6738 0.0 1.9 441812 76064 ? S Dec09 6:43 php-fpm: pool www
www 6737 0.0 2.3 434280 90192 ? S Dec09 6:29 php-fpm: pool www
www 6736 0.0 2.4 460112 93820 ? S Dec09 6:29 php-fpm: pool www
占用内存最多的10个进程
[root@dameng linuxscript]# ps aux|head -1;ps aux|sort -rn -k +4|head
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
www 1183 0.0 2.6 445260 100948 ? S Dec09 7:05 php-fpm: pool www
www 1177 0.0 2.6 457820 99796 ? S Dec09 6:54 php-fpm: pool www
www 1176 0.0 2.6 456788 100032 ? S Dec09 6:31 php-fpm: pool www
www 1179 0.0 2.5 438904 98660 ? S Dec09 6:32 php-fpm: pool www
www 7384 0.0 2.4 436428 91832 ? S Dec09 6:26 php-fpm: pool www
www 73344 0.0 2.4 428988 93996 ? S Dec12 3:25 php-fpm: pool www
www 6787 0.0 2.4 441144 92476 ? S Dec09 6:29 php-fpm: pool www
www 6785 0.0 2.4 446040 92264 ? S Dec09 6:30 php-fpm: pool www
www 6736 0.0 2.4 460112 93820 ? S Dec09 6:29 php-fpm: pool www
www 1191 0.0 2.4 440416 94024 ? S Dec09 7:10 php-fpm: pool www
可以看到除去nginx的两个进程,其余全部是php-fpm。
查看当前php-fpm总进程数
[root@dameng ~]# ps -ylC php-fpm --sort:rss
S UID PID PPID C PRI NI RSS SZ WCHAN TTY TIME CMD
S 0 900 1 0 80 0 4268 59433 - ? 00:00:10 php-fpm
S 1005 1174 900 0 80 0 10196 97401 - ? 00:07:09 php-fpm
S 1005 1185 900 0 80 0 11732 100252 - ? 00:06:29 php-fpm
S 1005 107461 900 0 80 0 31796 97600 - ? 00:00:19 php-fpm
S 1005 107459 900 0 80 0 66224 104786 - ? 00:00:20 php-fpm
S 1005 107452 900 0 80 0 73024 104239 - ? 00:00:20 php-fpm
S 1005 107451 900 0 80 0 76952 108688 - ? 00:00:19 php-fpm
S 1005 6463 900 0 80 0 79508 108117 - ? 00:06:31 php-fpm
S 1005 6576 900 0 80 0 82336 113815 - ? 00:06:32 php-fpm
S 1005 73344 900 0 80 0 82372 107247 - ? 00:03:25 php-fpm
S 1005 1193 900 0 80 0 82636 109523 - ? 00:06:28 php-fpm
S 1005 1184 900 0 80 0 84272 109207 - ? 00:06:32 php-fpm
S 1005 1180 900 0 80 0 84936 109765 - ? 00:06:50 php-fpm
S 1005 1189 900 0 80 0 85408 113732 - ? 00:06:32 php-fpm
S 1005 6737 900 0 80 0 85636 108570 - ? 00:06:29 php-fpm
S 1005 1191 900 0 80 0 86452 110104 - ? 00:07:10 php-fpm
S 1005 107467 900 0 80 0 86716 105308 - ? 00:00:19 php-fpm
S 1005 107436 900 0 80 0 86920 106680 - ? 00:00:20 php-fpm
S 1005 1178 900 0 80 0 88236 108623 - ? 00:06:29 php-fpm
S 1005 1187 900 0 80 0 88968 108701 - ? 00:06:33 php-fpm
S 1005 1188 900 0 80 0 89208 109055 - ? 00:06:30 php-fpm
S 1005 87009 900 0 80 0 89692 105626 - ? 00:01:31 php-fpm
S 1005 1181 900 0 80 0 91280 108432 - ? 00:06:31 php-fpm
S 1005 107466 900 0 80 0 91612 106331 - ? 00:00:20 php-fpm
S 1005 7384 900 0 80 0 91716 109107 - ? 00:06:26 php-fpm
S 1005 6787 900 0 80 0 92396 110286 - ? 00:06:29 php-fpm
S 1005 107462 900 0 80 0 93112 105760 - ? 00:00:19 php-fpm
S 1005 1182 900 0 80 0 93404 108442 - ? 00:06:32 php-fpm
S 1005 6736 900 0 80 0 93448 115028 - ? 00:06:29 php-fpm
S 1005 6785 900 0 80 0 93800 111510 - ? 00:06:30 php-fpm
S 1005 107460 900 0 80 0 94540 107895 - ? 00:00:20 php-fpm
S 1005 1190 900 0 80 0 94812 108684 - ? 00:06:29 php-fpm
S 1005 1177 900 0 80 0 95120 114455 - ? 00:06:54 php-fpm
S 1005 1186 900 0 80 0 95132 119251 - ? 00:06:34 php-fpm
S 1005 107468 900 0 80 0 95508 107337 - ? 00:00:20 php-fpm
S 1005 6738 900 0 80 0 96216 109941 - ? 00:06:44 php-fpm
S 1005 1192 900 0 80 0 96412 108828 - ? 00:06:28 php-fpm
S 1005 1175 900 0 80 0 96776 110023 - ? 00:07:17 php-fpm
S 1005 1179 900 0 80 0 97792 109726 - ? 00:06:32 php-fpm
S 1005 1183 900 0 80 0 98208 111315 - ? 00:07:05 php-fpm
S 1005 1176 900 0 80 0 98856 114197 - ? 00:06:31 php-fpm
[root@dameng ~]# ps -ylC php-fpm --sort:rss|wc -l
42
[root@dameng ~]# ps -fe |grep "php-fpm"|grep "pool"|wc -l
40
查看当前php-fpm进程的内存占用情况及启动时间
[root@dameng ~]# ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'|grep www|sort -nrk5
87009 php-fpm php-fpm: pool www 0.0 89692 422504 Dec13 www 1005
77548 nginx nginx: worker process 0.0 3932 97456 Dec12 www 1005
77547 nginx nginx: worker process 0.0 5472 97460 Dec12 www 1005
7384 php-fpm php-fpm: pool www 0.0 91716 436428 Dec09 www 1005
73344 php-fpm php-fpm: pool www 0.0 82372 428988 Dec12 www 1005
6787 php-fpm php-fpm: pool www 0.0 92396 441144 Dec09 www 1005
6785 php-fpm php-fpm: pool www 0.0 93800 446040 Dec09 www 1005
6738 php-fpm php-fpm: pool www 0.0 96216 439764 Dec09 www 1005
6737 php-fpm php-fpm: pool www 0.0 85636 434280 Dec09 www 1005
6736 php-fpm php-fpm: pool www 0.0 93448 460112 Dec09 www 1005
6576 php-fpm php-fpm: pool www 0.0 82336 455260 Dec09 www 1005
6463 php-fpm php-fpm: pool www 0.0 79508 432468 Dec09 www 1005
1193 php-fpm php-fpm: pool www 0.0 82636 438092 Dec09 www 1005
1192 php-fpm php-fpm: pool www 0.0 96412 435312 Dec09 www 1005
1191 php-fpm php-fpm: pool www 0.0 86452 440416 Dec09 www 1005
1190 php-fpm php-fpm: pool www 0.0 94812 434736 Dec09 www 1005
1189 php-fpm php-fpm: pool www 0.0 85408 454928 Dec09 www 1005
1188 php-fpm php-fpm: pool www 0.0 89208 436220 Dec09 www 1005
1187 php-fpm php-fpm: pool www 0.0 88968 434804 Dec09 www 1005
1186 php-fpm php-fpm: pool www 0.0 95132 477004 Dec09 www 1005
1185 php-fpm php-fpm: pool www 0.0 11732 401008 Dec09 www 1005
1184 php-fpm php-fpm: pool www 0.0 84272 436828 Dec09 www 1005
1183 php-fpm php-fpm: pool www 0.0 98208 445260 Dec09 www 1005
1182 php-fpm php-fpm: pool www 0.0 93404 433768 Dec09 www 1005
1181 php-fpm php-fpm: pool www 0.0 91280 433728 Dec09 www 1005
1180 php-fpm php-fpm: pool www 0.0 84936 439060 Dec09 www 1005
1179 php-fpm php-fpm: pool www 0.0 97792 438904 Dec09 www 1005
1178 php-fpm php-fpm: pool www 0.0 88236 434492 Dec09 www 1005
1177 php-fpm php-fpm: pool www 0.0 95120 457820 Dec09 www 1005
1176 php-fpm php-fpm: pool www 0.0 98856 456788 Dec09 www 1005
1175 php-fpm php-fpm: pool www 0.0 96776 440092 Dec09 www 1005
1174 php-fpm php-fpm: pool www 0.0 10196 389604 Dec09 www 1005
110196 grep grep --color=auto www 0.0 1108 12140 10:57 root 0
107468 php-fpm php-fpm: pool www 0.0 95508 429348 Dec15 www 1005
107467 php-fpm php-fpm: pool www 0.0 86716 421232 Dec15 www 1005
107466 php-fpm php-fpm: pool www 0.0 91612 425324 Dec15 www 1005
107462 php-fpm php-fpm: pool www 0.0 93112 423040 Dec15 www 1005
107461 php-fpm php-fpm: pool www 0.0 31796 390400 Dec15 www 1005
107460 php-fpm php-fpm: pool www 0.0 94540 431580 Dec15 www 1005
107459 php-fpm php-fpm: pool www 0.0 66224 419144 Dec15 www 1005
107452 php-fpm php-fpm: pool www 0.0 73024 416956 Dec15 www 1005
107451 php-fpm php-fpm: pool www 0.0 76952 434752 Dec15 www 1005
107436 php-fpm php-fpm: pool www 0.0 86920 426720 Dec15 www 1005
查看当前php-fpm进程平均占用内存情况
[root@dameng ~]# ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'
79M
所以,罪魁祸首就是php-fpm。
三、解决方法 {#三、解决方法}
php-fpm.conf就是php-fpm的配置文件,一般路径为:/usr/local/php/etc/php-fpm.conf
修改如下参数
pm = dynamic
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 100
- pm = dynamic #指定进程管理方式,有3种可供选择:static、dynamic和ondemand。
- pm.max_children = 30 #static模式下创建的子进程数或dynamic模式下同一时刻允许最大的php-fpm子进程数量。
- pm.start_servers = 20 #动态方式下的起始php-fpm进程数量。
- pm.min_spare_servers = 10 #动态方式下服务器空闲时最小php-fpm进程数量。
- pm.max_spare_servers = 30 #动态方式下服务器空闲时最大php-fpm进程数量。
- pm.max_requests = 300 #php-fpm子进程能处理的最大请求数。
其中pm.max_requests是设置每个子进程重生之前服务的请求数,对于可能存在内存泄漏的第三方模块来说是非常有用的。
注意
pm.max_requests设置得太小也容易出现无进程可用(502状态),一般来说,普通网站设置max_requests 300~500 合适,但也要结合pm.start_servers和你的网站访问量来看,也可以适当调大和减少,这个是因情况而异的。
修改完配置文件后,保存退出,检测配置文件语法是否正确
[root@dameng ~]# /usr/local/php/sbin/php-fpm -t
[16-Dec-2024 13:07:50] NOTICE: configuration file /usr/local/php/etc/php-fpm.conf test is successful
重启php-fpm
[root@dameng etc]# service php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm done
再次查看服务器内存使用情况
[root@dameng etc]# free -m
total used free shared buff/cache available
Mem: 3736 289 3160 2 285 3224
Swap: 4095 895 3200
可以看到服务器内存使用率已经降下来了,后续再做观察。