服务器内存被php-fpm占满导致网站变慢
本文于 107 天前发布,最后更新于 103 天前

一、问题描述

过了个周末发现博客网站变得很慢,发布文章特别迟钝。经过登录服务器查看资源使用情况发现是 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

可以看到服务器内存使用率已经降下来了,后续再做观察。

经过一周的观察,服务器内存可以稳定下来,available 始终保持在 1000 左右,表现还算良好。但是,在我使用 WordPress 插件 Duplicator 进行备份后发现,available 又减少了一百多,看着不是很舒服。所以决定在服务器添加定时任务,每天凌晨 1 点重启 php-fpm 服务以释放内存。

crontab -e
## 新增内容
0 1 * * * service php-fpm restart
## 保存退出

这样服务器内存可以始终保持在一个健康的水平。

暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇