服务器突然变慢、进程莫名其妙被杀掉、MySQL 无缘无故挂掉... 如果你遇到这些情况,十有八九是内存不足触发了 OOM Killer。这篇文章教你怎么诊断和解决 VPS 内存不足的问题。
OOM 是 Out of Memory 的缩写。当 Linux 系统内存耗尽时,内核会启动 OOM Killer 机制,选择性地杀掉一些进程来释放内存,保证系统不会完全死掉。
被杀掉的进程通常是内存占用大的,比如 MySQL、Java 应用、Node.js 服务等。这就是为什么你的数据库或网站服务会突然挂掉。
# 搜索 OOM 相关日志
dmesg | grep -i "out of memory"
dmesg | grep -i "oom"
# 或者查看 syslog
grep -i "oom" /var/log/syslog
grep -i "oom" /var/log/messages
如果看到类似这样的输出,说明确实发生了 OOM:
Out of memory: Killed process 1234 (mysqld) total-vm:2048000kB, anon-rss:1024000kB
# 查看内存概况
free -h
# 输出示例:
# total used free shared buff/cache available
# Mem: 1.9Gi 1.5Gi 128Mi 64Mi 300Mi 200Mi
# Swap: 0B 0B 0B
重点看 available 列,这才是真正可用的内存。如果这个值很小(比如低于 100MB),说明内存确实紧张。
# 按内存占用排序显示进程
ps aux --sort=-%mem | head -20
# 或者用 top,按 M 键按内存排序
top
如果你的 VPS 没有配置 Swap,强烈建议加上。Swap 可以在内存不足时提供缓冲,虽然速度慢一些,但总比进程被杀好。
# 检查是否有 swap
swapon --show
# 如果没有,创建 2G 的 swap 文件
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 设置开机自动挂载
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Swap 大小建议:
- 1GB 内存:Swap 设置 1-2GB
- 2GB 内存:Swap 设置 2GB
- 4GB 以上:Swap 设置 2-4GB 即可
MySQL 是内存大户,小内存 VPS 必须调优。编辑配置文件:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
1GB 内存 VPS 推荐配置:
[mysqld]
# 关键参数
innodb_buffer_pool_size = 128M
innodb_log_buffer_size = 8M
key_buffer_size = 16M
# 连接相关
max_connections = 50
thread_cache_size = 8
# 临时表
tmp_table_size = 16M
max_heap_table_size = 16M
# 查询缓存(MySQL 8.0 已移除)
query_cache_size = 0
query_cache_type = 0
修改后重启 MySQL:
sudo systemctl restart mysql
如果跑 WordPress 或其他 PHP 应用,PHP-FPM 的进程数也要控制。
编辑 PHP-FPM 配置:
# 路径可能不同,根据你的 PHP 版本调整
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
1GB 内存推荐配置:
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 500
使用 systemd 可以限制服务的最大内存使用:
# 编辑服务配置
sudo systemctl edit mysql
添加内存限制:
[Service]
MemoryMax=512M
MemoryHigh=400M
这样 MySQL 最多只能使用 512MB 内存,超过 400MB 时系统会尝试回收内存。
可以降低重要进程被杀的优先级:
# 查看进程的 oom_score(分数越高越容易被杀)
cat /proc/$(pidof mysqld)/oom_score
# 调整 oom_score_adj(范围 -1000 到 1000,-1000 表示永不被杀)
echo -500 > /proc/$(pidof mysqld)/oom_score_adj
要永久生效,在 systemd 服务文件中添加:
[Service]
OOMScoreAdjust=-500
写一个简单的内存监控脚本,内存过低时发送告警:
#!/bin/bash
# /usr/local/bin/memory-monitor.sh
THRESHOLD=100 # 可用内存低于 100MB 时告警
available=$(free -m | awk '/Mem:/ {print $7}')
if [ $available -lt $THRESHOLD ]; then
echo "警告:可用内存仅剩 ${available}MB" | mail -s "VPS 内存告警" [email protected]
fi
配合 cron 定时执行:
# 每 5 分钟检查一次
*/5 * * * * /usr/local/bin/memory-monitor.sh
如果你已经:
- 添加了 Swap
- 优化了各服务的内存配置
- 关闭了不必要的服务
但内存还是经常不够用,那就该考虑升级 VPS 配置了。一般来说:
- 单个小站点:1GB 内存够用
- WordPress + 几个小服务:2GB 比较舒适
- 多站点或 Java 应用:4GB 起步
处理 OOM 问题的思路:
- 先确认 - 查日志确认是否真的发生了 OOM
- 找原因 - 找出内存占用大的进程
- 加缓冲 - 没有 Swap 的话先加上
- 做优化 - 调整 MySQL、PHP-FPM 等服务配置
- 设限制 - 必要时用 systemd 限制进程内存
- 做监控 - 设置告警,问题早发现早处理
小内存 VPS 跑服务需要精打细算,但只要配置得当,1GB 内存跑个人博客或小项目完全没问题。
