检查代码中是否存在内存泄漏(如未释放的变量、循环引用)或不必要的资源消耗(如重复查询数据库、大文件加载)。使用性能分析工具(如Xdebug、Blackfire)定位内存占用高的代码段,针对性修复。例如,及时 unset() 不再使用的变量,避免全局变量长期占用内存。
PHP-FPM的进程管理策略直接影响内存占用,需根据服务器资源(内存、CPU核心数)调整以下关键参数(位于/etc/php/{version}/fpm/pool.d/www.conf):
ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'获取)。例如,1GB内存服务器若单个进程平均50MB,则pm.max_children建议设为15-20(1000MB - 200MB系统预留)/50MB≈16-20)。OPcache可缓存已编译的PHP脚本,减少每次请求的编译开销,显著降低内存占用。确保php.ini中启用了OPcache:
opcache.enable=1
opcache.memory_consumption=128 ; 缓存大小(MB),根据服务器内存调整
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60 ; 脚本更新检查频率(秒)
重启PHP-FPM使配置生效:sudo systemctl restart php{version}-fpm。
通过php.ini禁用未使用的扩展(如xdebug、gd(若无需图片处理)、soap等),减少内存占用。例如,注释掉extension=xdebug.so或extension=gd.so,重启PHP-FPM即可。
使用Nginx或Apache的限速模块(如Nginx的limit_req_zone)限制单个IP的请求速率,防止恶意请求或突发流量导致PHP-FPM进程数激增。例如,Nginx配置:
http {
limit_req_zone $binary_remote_addr zone=req_per_ip:10m rate=10r/s;
server {
location / {
limit_req zone=req_per_ip burst=20 nodelay;
}
}
}
这可有效控制并发请求,避免PHP-FPM过载。
新版本PHP(如8.0+)通常包含性能改进和内存管理优化(如更高效的垃圾回收机制),升级后可降低内存占用。例如,PHP 8.0的内存使用比PHP 7.4平均减少10%-20%。升级前需测试应用兼容性。
通过Memcached或Redis缓存频繁访问的数据库查询结果(如商品信息、用户会话),减少PHP脚本对数据库的重复查询,降低内存和CPU负载。例如,使用Redis缓存查询结果:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$key = 'product_' . $productId;
if ($redis->exists($key)) {
$product = unserialize($redis->get($key));
} else {
$product = $db->query("SELECT * FROM products WHERE id = $productId")->fetch();
$redis->setex($key, 3600, serialize($product)); // 缓存1小时
}
使用工具(如htop、glances、php-fpm-exporter+Prometheus+Grafana)实时监控PHP-FPM的内存占用、进程数、请求处理时间等指标,及时发现异常。例如,htop可按内存排序查看进程,glances可监控系统整体资源使用情况。
若部分脚本确实需要更多内存(如处理大文件上传),可适当调整memory_limit(位于php.ini或www.conf),但需避免设置过高(如超过服务器内存的70%),防止内存耗尽。例如:
memory_limit = 256M ; 根据实际需求调整
若应用无需长时间运行(如定时任务),可使用ondemand模式(pm = ondemand),该模式下PHP-FPM会根据请求动态创建进程,闲置进程会在process_idle_timeout(如10秒)后自动销毁,减少内存占用。但需注意,高峰期可能出现进程创建延迟。