小站搭好之后,发现一个让人抓狂的问题:页面时而秒开、时而卡十几秒不动,访客还以为我跑路了😭 排查了一圈,罪魁祸首是 PHP-FPM 的并发配置——2 核小服务器,被默认配置按在地上摩擦。
症状
典型表现:访问时好时坏,偶尔请求直接超时,后台操作转圈半天。如果你也是小内存小鸡遇到这种「抽风」,八成是 PHP-FPM 进程打满了。
原因:pm.max_children 的锅
PHP-FPM 默认是 pm = dynamic 模式,pm.max_children 默认为 5。听起来 5 个进程不少?错!
- 2 核 CPU 上,5 个 PHP 进程同时跑,CPU 直接吃满,剩下排队请求全部卡死
- 每个 PHP 进程内存占用 30~60MB,2G 内存分分钟不够
- 一旦有慢请求(比如连数据库卡了),5 个进程全被占住,整个站就「假死」了
解决方案
# 编辑 www.conf
sudo nano /etc/php/7.4/fpm/pool.d/www.conf
# 改成 ondemand 模式(按需启动,不占资源)
pm = ondemand
pm.max_children = 4
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500
# 重启生效
sudo systemctl restart php7.4-fpm
解释一下关键决策:
- pm = ondemand:空闲时一个 PHP 进程都不留,来请求才拉起来,内存压力骤降(注意:这个选项跟 WordPress 的某些插件偶有兼容问题,如果发现异常可以退回 dynamic,但要调小 max_children)
- max_children 设 4:2 核 2G 的黄金平衡点,再多 CPU 就冒烟了
- max_requests = 500:进程处理 500 个请求后自动重启,防止内存泄漏越积越大
验证
# 看进程数和负载
ps aux | grep php-fpm | grep -v grep | wc -l
top -bn1 | head -5
改完之后,站子明显稳了:高峰期也保持 1 秒内响应,再也不怕访客问我「站是不是挂了」🤣
小结
小服务器优化第一课:别让进程数超过核数太多。宁可慢点处理,也别让整个站假死。剩下的内存优化(OPcache、Redis 缓存)坑更野,改天再写一篇~