为什么LAMP服务器容易吃内存?
LAMP(Linux + Apache + MySQL + PHP)是最经典的Web服务器架构之一,但它有个老毛病——内存占用偏高。尤其当你用的是1GB或2GB的小内存VPS时,如果不做优化,轻则Swap频繁读写导致卡顿,重则OOM Killer直接把MySQL进程干掉,网站直接502。
常见的内存杀手:
- Apache的Prefork模式:每个连接占用一个进程,并发一高内存就爆炸
- MySQL默认配置:InnoDB Buffer Pool等参数默认值偏大,小机器扛不住
- PHP-FPM进程管理:static模式下进程数写死,空闲时也占着内存不放
- 没有Swap分区:内存耗尽时连缓冲都没有
一、Apache内存优化
1. 切换到Worker或Event MPM
Prefork模式每个连接一个进程,内存开销巨大。Event MPM使用线程处理连接,内存效率提升显著:
# 查看当前MPM
apachectl -V | grep MPM
# Ubuntu切换到Event
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2
2. 调整进程/线程参数
编辑Apache配置(通常在/etc/apache2/mods-available/mpm_event.conf):
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 3000
核心原则:MaxRequestWorkers不要超过你的内存能承载的进程数。估算公式:
可用Worker数 = (总内存 – 系统预留 – MySQL占用 – PHP占用) / 单个Apache进程内存
3. 启用KeepAlive但限制超时
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 3
KeepAliveTimeout设为3秒而非默认5秒,能更快释放连接。
二、MySQL内存优化
1. InnoDB Buffer Pool
这是MySQL最大的内存消费者。建议设为可用内存的50%-70%:
# 1GB内存VPS推荐
innodb_buffer_pool_size = 256M
# 2GB内存VPS推荐
innodb_buffer_pool_size = 512M
2. 其他关键参数
# 减少连接内存
max_connections = 50
table_open_cache = 64
thread_cache_size = 8
# 临时表优化
tmp_table_size = 32M
max_heap_table_size = 32M
# 查询缓存(MySQL 8.0已移除,5.7可用)
query_cache_type = 1
query_cache_size = 32M
3. 慢查询排查
优化内存的另一个角度是减少不必要的查询开销:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
慢查询少了,内存压力自然下降。
三、PHP-FPM内存优化
1. 选择dynamic进程管理模式
pm = dynamic
pm.max_children = 20
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500
- dynamic模式:按需创建和销毁进程,内存利用率最高
- ondemand模式:更激进,完全按需,但突发流量时响应慢
- static模式:内存占用固定,适合大内存服务器
2. 限制PHP内存上限
php_admin_value[memory_limit] = 128M
对于1GB内存的VPS,128M是合理上限。单个脚本吃掉过多内存时会被自动终止。
3. 开启OPcache
opcache.enable = 1
opcache.memory_consumption = 64
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 4000
opcache.revalidate_freq = 60
OPcache将编译后的PHP字节码缓存在内存中,避免重复编译,间接节省CPU和内存开销。
四、系统层面优化
1. 添加Swap分区
即使SSD的Swap比内存慢,也比OOM强:
# 创建2GB Swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 调低swappiness,优先用物理内存
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
2. 调整内核参数
# 减少TCP连接内存占用
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
# 文件描述符优化
fs.file-max = 65535
3. 使用轻量替代方案
如果优化后内存仍然紧张,考虑替换组件:
| 原组件 | 替代方案 | 内存节省 |
|---|---|---|
| Apache | Nginx | 50%-70% |
| MySQL | MariaDB | 10%-20% |
| PHP-FPM | PHP-FPM + OPcache | 已含在优化中 |
Nginx的事件驱动架构在高并发下内存占用仅为Apache的1/3到1/5。
五、监控与持续优化
实用监控命令
# 实时内存概览
free -h
# 按进程排序内存占用
ps aux --sort=-%mem | head -20
# Apache进程数和内存
ps -ylC apache2 --sort:rss | head
# MySQL内存使用
mysql -e "SHOW ENGINE INNODB STATUS\G" | grep "Buffer pool"
定期检查清单
- 每周检查
free -h确认Swap使用率 - 每月审查MySQL慢查询日志
- 流量高峰期观察PHP-FPM进程数是否合理
- 更新软件版本,新版本通常有性能改进
总结
LAMP服务器内存优化是一个系统工程,核心思路是:减少不必要的占用 + 按需分配 + 持续监控。对于1-2GB的小内存VPS,优先做三件事:
- Apache切换Event MPM并限制Worker数
- MySQL调低Buffer Pool和连接数
- PHP-FPM使用dynamic模式 + OPcache
这三步做完,通常能节省30%-50%的内存,让小机器也能稳定运行。