服务器内存不足导致网站502,优化手段
当网站访问出现502 Bad Gateway,同时服务器SSH登录卡顿、命令响应慢,大概率是内存耗尽导致PHP-FPM或MySQL进程被系统强制杀死。
本文针对内存不足引发的502问题,从确认瓶颈、调整关键服务参数到验证效果,给出零基础也能照做的优化流程。
先确认是不是内存真的不够
登录服务器,执行以下命令查看内存和Swap使用情况:
free -h
重点看available列和Swap行的used值。如果available小于总内存的10%,或者Swap used持续增长,说明物理内存已经不够。
接着查看最近被系统杀掉的进程:
dmesg -T | grep -i 'killed process'
如果输出里出现php-fpm或mysqld,基本可以确定502是内存不足引起的。
再快速看一眼当前内存占用排名:
ps aux --sort=-%mem | head -10
这一步能帮你判断是PHP-FPM进程太多,还是MySQL缓冲池设得太大。
调整PHP-FPM进程数,减少内存占用
PHP-FPM是内存消耗大户,每个子进程约占30-80MB。
如果pm.max_children设置过大,内存很快被吃光。
宝塔面板操作路径: 软件商店 → PHP 7.x → 配置修改 → 找到pm.max_children。
命令行编辑路径(以PHP 7.4为例):
vim /www/server/php/74/etc/php-fpm.d/www.conf
关键参数建议:
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500
pm.max_children的估算方法:用free -h看到的available内存,减去MySQL和其他服务占用,再除以每个PHP-FPM进程的平均内存(约50MB)。
例如available有1GB,MySQL占300MB,剩余700MB,则max_children设为10-14比较安全。
改完后重载PHP-FPM:
systemctl reload php-fpm-74
或宝塔面板直接点“重载配置”。
压低MySQL内存占用
MySQL默认配置可能占用大量内存,尤其是innodb_buffer_pool_size。
对于小内存服务器(1核1G或1核2G),建议主动限制。
编辑MySQL配置文件:
vim /etc/my.cnf
在[mysqld]段落下调整:
innodb_buffer_pool_size = 128M
performance_schema = OFF
max_connections = 50
table_open_cache = 64
innodb_buffer_pool_size通常设为可用内存的50%-60%,
但小内存机器不要超过256M。performance_schema关闭后能省下几十MB内存,
对性能监控要求不高的站点可以关。
重启MySQL生效:
systemctl restart mysqld
控制Nginx连接数和缓冲区
Nginx本身内存占用不大,但每个连接都会消耗缓冲区。
如果并发连接数很高,内存也会被快速消耗。
编辑Nginx主配置:
vim /www/server/nginx/conf/nginx.conf
调整以下参数:
worker_connections 512;
keepalive_timeout 30;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
client_body_buffer_size 128k;
同时限制单个IP的并发连接数,防止被恶意刷流量:
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
limit_conn addr 10;
}
改完执行:
nginx -t && nginx -s reload
几个容易踩的坑
- 不要直接关闭Swap。 内存不足时Swap能救急,虽然慢但比进程被杀好。如果Swap也没了,系统会直接OOM Killer杀进程,502会更频繁。
- 调整
pm.max_children不要一步加太大。 先降低到安全值,观察网站是否正常,再根据实际负载微调。 - MySQL的
innodb_buffer_pool_size不是越大越好。 小内存机器设太大反而导致Swap频繁读写,性能更差。 - 宝塔面板的“内存优化”插件可以辅助观察,但不要依赖它自动改配置。 自动优化可能不贴合你的实际业务。
- 如果优化后内存依然吃紧,考虑升级服务器内存或迁移到更高配置的实例,这是最直接的解决方式。
验证优化是否生效
完成上述调整后,重启PHP-FPM、MySQL和Nginx,然后持续观察:
watch -n 2 free -h
理想状态: available内存稳定在总内存的20%以上,Swap used不再持续增长。
同时用浏览器或curl多次访问网站,确认不再出现502。
curl -I http://你的域名
返回HTTP/1.1 200 OK即表示网站恢复正常。
如果仍然502,检查PHP-FPM错误日志:
tail -f /www/server/php/74/var/log/php-fpm.log
日志中如果出现server reached pm.max_children setting,说明并发还是太高,需要继续降低pm.max_children或排查是否有异常请求。
内存不足导致的502,核心思路是“先定位谁在吃内存,再限制它的上限”。
PHP-FPM、MySQL、Nginx三个环节按顺序检查一遍,大部分小内存服务器的502问题都能明显缓解。
如果业务持续增长,及时升级内存比反复调参更省心。