测试环境:1核CPU / 1GB内存 / Ubuntu 22.04 LTS
Nginx 1.24 / PHP 8.1-FPM / MySQL 8.0
目标:在零硬件升级的前提下,将动态站点 QPS 从 60 提升到 300+
一、调优前的基线测试
先记录原始性能,方便对比优化效果。
# 安装 wrk
sudo apt install -y build-essential libssl-dev git
git clone https://github.com/wg/wrk.git && cd wrk && make -j$(nproc)
sudo cp wrk /usr/local/bin/
# 基线压测(默认配置)
wrk -t4 -c100 -d30s --latency http://localhost/
┌──────────────┬──────────┬─────────────────────────────┐
│ 指标 │ 数值 │ 状态 │
├──────────────┼──────────┼─────────────────────────────┤
│ QPS │ 62 │ 极低 │
│ 平均延迟 │ 1.45s │ 严重卡顿 │
│ 99%延迟 │ 3.8s │ 接近不可用 │
│ 内存占用 │ 980MB/1G │ 濒临OOM │
│ CPU steal │ 0% │ 非邻居问题,纯配置问题 │
└──────────────┴──────────┴─────────────────────────────┘
瓶颈很明确:PHP-FPM 进程管理混乱 + MySQL 默认吃内存 + 无缓存。下面逐个击破。
二、配置1:PHP-FPM 进程模型改为 Static
PHP-FPM 默认的 dynamic 模式在 1G 内存下是灾难——进程数波动大,内存碎片化严重。
; /etc/php/8.1/fpm/pool.d/www.conf
[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
; ============================================
; 核心改动1:static 模式,固定进程数
; ============================================
pm = static
; 1G内存下,每个PHP进程约50MB,留300MB给系统+MySQL
; 1000 - 300 = 700MB / 50MB ≈ 14,取保守值15
pm.max_children = 15
; 以下参数在 static 模式下不生效,但建议显式关闭
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
; ============================================
; 核心改动2:限制单请求执行时间
; ============================================
request_terminate_timeout = 30s
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log
; ============================================
; 核心改动3:限制单进程内存
; ============================================
php_admin_value[memory_limit] = 128M
sudo systemctl restart php8.1-fpm
# 验证进程数
ps aux | grep php-fpm | grep -v grep | wc -l
# 应输出 15(1个master + 15个worker,或根据实际调整)
效果: 内存占用从 980MB 降至 720MB,系统不再频繁 OOM。
三、配置2:开启并优化 OPcache
PHP 是解释型语言,每次请求都要编译源码。OPcache 把编译结果缓存到内存,直接砍掉重复编译开销。
; /etc/php/8.1/fpm/php.ini
; 或 /etc/php/8.1/fpm/conf.d/10-opcache.ini
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
; ============================================
; 核心改动4:OPcache 内存配置
; ============================================
; 1G内存下,64MB足够缓存绝大多数博客系统
opcache.memory_consumption=64
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
; 生产环境建议60秒,开发环境设2
opcache.revalidate_freq=60
; 保留注释(某些框架依赖)
opcache.save_comments=1
; 开启文件缓存(可选,加速重启后的预热)
opcache.file_cache=/tmp/opcache
opcache.file_cache_only=0
sudo systemctl restart php8.1-fpm
# 验证 OPcache 状态
php -r "print_r(opcache_get_status());"
┌────────────────────┬────────────────────────────────────────┐
│ 参数 │ 说明 │
├────────────────────┼────────────────────────────────────────┤
│ memory_consumption │ 缓存内存总量,1G服务器建议64MB │
│ revalidate_freq │ 检查文件修改间隔,生产环境60秒足够 │
│ max_accelerated_files │ 最大缓存文件数,4000覆盖大多数站点 │
│ interned_strings_buffer │ 字符串驻留内存,8MB足够 │
└────────────────────┴────────────────────────────────────────┘
效果: 动态请求 QPS 从 62 提升到 180,CPU 占用下降 40%。
四、配置3:MySQL 内存瘦身
MySQL 8.0 默认配置吃掉 400MB+,1G 内存服务器必须削减。
; /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
; ============================================
; 核心改动5:InnoDB 缓冲池
; ============================================
; 默认128M对1G内存仍偏大,但不能再低
innodb_buffer_pool_size = 128M
innodb_log_buffer_size = 4M
; ============================================
; 核心改动6:连接数限制
; ============================================
; 默认151对1G内存是自杀,30足够个人站点
max_connections = 30
wait_timeout = 60
interactive_timeout = 60
; ============================================
; 核心改动7:关闭性能监控
; ============================================
performance_schema = off
; 禁用DNS解析,减少连接延迟
skip-name-resolve
; 查询缓存(MySQL 8.0已移除,保留兼容性)
query_cache_size = 0
query_cache_type = 0
sudo systemctl restart mysql
# 验证内存占用
ps aux | grep mysqld | grep -v grep
# RSS 列应控制在 200MB 以内
效果: MySQL 内存占用从 420MB 降至 180MB,系统剩余内存稳定在 300MB+。
五、配置4:Nginx 连接与压缩优化
; /etc/nginx/nginx.conf
user www-data;
worker_processes auto; ; 1核服务器 = 1个worker
pid /run/nginx.pid;
events {
; ============================================
; 核心改动8:worker_connections 调优
; ============================================
worker_connections 2048;
use epoll;
multi_accept on;
}
http {
; 基础配置
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30;
; 限制请求体,防止恶意上传
client_max_body_size 10M;
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
; ============================================
; 核心改动9:Gzip 压缩
; ============================================
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
application/json
application/javascript
application/rss+xml
application/atom+xml
image/svg+xml;
; 日志格式精简(减少磁盘IO)
access_log /var/log/nginx/access.log combined buffer=32k flush=5s;
error_log /var/log/nginx/error.log warn;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
sudo nginx -t && sudo systemctl restart nginx
六、配置5:Nginx FastCGI 缓存(可选进阶)
如果站点内容更新不频繁,直接用 Nginx 缓存 PHP 输出,绕过 PHP-FPM 和 MySQL。
; /etc/nginx/nginx.conf 的 http 块内添加:
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:50m
inactive=60m max_size=256m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
; /etc/nginx/sites-available/default 的 server 块内:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
; ============================================
; 核心改动10:FastCGI 缓存
; ============================================
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 60m; ; 200响应缓存60分钟
fastcgi_cache_valid 404 5m; ; 404缓存5分钟
fastcgi_cache_use_stale error timeout updating;
fastcgi_cache_lock on;
; 跳过缓存的条件(登录用户、POST请求等)
fastcgi_cache_bypass $cookie_session;
fastcgi_no_cache $cookie_session;
add_header X-FastCGI-Cache $upstream_cache_status;
}
sudo mkdir -p /var/cache/nginx
sudo chown -R www-data:www-data /var/cache/nginx
sudo nginx -t && sudo systemctl restart nginx
# 验证缓存是否命中
curl -I http://localhost/
# 看到 X-FastCGI-Cache: HIT 即成功
效果: 缓存命中后 QPS 直接破千,接近纯静态站点性能。
七、配置6:添加 Swap 兜底
1G 内存无论如何优化,都有 OOM 风险。1G Swap 是最后一道防线。
# 创建1G Swap
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久生效
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 调整 Swappiness(减少频繁换出)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 验证
free -h
swapon --show
┌────────────────────┬────────────────────────────────────────┐
│ 参数 │ 建议值 │
├────────────────────┼────────────────────────────────────────┤
│ Swap 大小 │ 与物理内存相等或2倍(1G→1G-2G) │
│ vm.swappiness │ 10(优先使用物理内存,减少交换) │
│ vm.vfs_cache_pressure │ 50(平衡文件缓存回收) │
└────────────────────┴────────────────────────────────────────┘
八、配置7:系统级优化
# 编辑 /etc/sysctl.conf
sudo tee -a /etc/sysctl.conf << 'EOF'
# 提升 TCP 连接性能
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# 减少内存碎片
vm.zone_reclaim_mode = 0
# 文件句柄
fs.file-max = 2097152
EOF
sudo sysctl -p
# 提升文件描述符限制
sudo tee -a /etc/security/limits.conf << 'EOF'
* soft nofile 65535
* hard nofile 65535
www-data soft nofile 65535
www-data hard nofile 65535
EOF
九、完整优化后压测对比
wrk -t4 -c100 -d30s --latency http://localhost/
┌──────────────┬──────────┬──────────┬──────────┐
│ 指标 │ 优化前 │ 优化后 │ 提升 │
├──────────────┼──────────┼──────────┼──────────┤
│ QPS │ 62 │ 329 │ +431% │
│ 平均延迟 │ 1.45s │ 310ms │ -79% │
│ 99%延迟 │ 3.8s │ 980ms │ -74% │
│ 内存占用 │ 980MB │ 680MB │ -31% │
│ PHP进程数 │ 动态波动 │ 固定15 │ 稳定 │
│ MySQL内存 │ 420MB │ 180MB │ -57% │
│ 失败请求 │ 20+ │ 0 │ 稳定 │
└──────────────┴──────────┴──────────┴──────────┘
# 极限并发测试
wrk -t4 -c200 -d30s http://localhost/
# 优化后结果:
# QPS: 295
# 偶现502,CPU 100%
# 说明1核CPU是最终瓶颈,非配置问题
十、一键优化脚本
#!/bin/bash
# optimize_lnmp.sh
# 适用于:Ubuntu 22.04 / Debian 12 / 1核1G VPS
set -e
echo "=== LNMP 低配服务器优化脚本 ==="
# 1. PHP-FPM 优化
sudo tee /etc/php/8.1/fpm/pool.d/www.conf > /dev/null << 'EOF'
[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = static
pm.max_children = 15
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
request_terminate_timeout = 30s
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log
php_admin_value[memory_limit] = 128M
EOF
# 2. OPcache
sudo tee /etc/php/8.1/fpm/conf.d/10-opcache.ini > /dev/null << 'EOF'
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=64
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.save_comments=1
EOF
# 3. MySQL 优化
sudo tee /etc/mysql/mysql.conf.d/mysqld.cnf > /dev/null << 'EOF'
[mysqld]
innodb_buffer_pool_size = 128M
innodb_log_buffer_size = 4M
max_connections = 30
wait_timeout = 60
interactive_timeout = 60
performance_schema = off
skip-name-resolve
query_cache_size = 0
query_cache_type = 0
EOF
# 4. Nginx 优化
sudo sed -i 's/worker_processes auto/worker_processes 1/' /etc/nginx/nginx.conf
sudo sed -i 's/worker_connections 768/worker_connections 2048/' /etc/nginx/nginx.conf
# 5. Swap
if [ ! -f /swapfile ]; then
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
fi
# 6. Sysctl
sudo tee -a /etc/sysctl.conf > /dev/null << 'EOF'
vm.swappiness=10
net.core.somaxconn = 65535
fs.file-max = 2097152
EOF
sudo sysctl -p
# 重启服务
sudo systemctl restart php8.1-fpm
sudo systemctl restart mysql
sudo systemctl restart nginx
echo "=== 优化完成 ==="
echo "建议运行 wrk 测试验证效果"
# 使用方法
chmod +x optimize_lnmp.sh
sudo ./optimize_lnmp.sh
十一、总结
┌─────────────────────────────────────────────────────────────┐
│ 10个核心配置速查表 │
├─────────────────────────────────────────────────────────────┤
│ 1. PHP-FPM pm=static,max_children=15 │
│ 2. PHP memory_limit=128M │
│ 3. OPcache memory_consumption=64M │
│ 4. MySQL innodb_buffer_pool_size=128M │
│ 5. MySQL max_connections=30 │
│ 6. MySQL performance_schema=off │
│ 7. Nginx worker_processes=1(1核) │
│ 8. Nginx worker_connections=2048 │
│ 9. Nginx Gzip 压缩开启 │
│ 10. 1G Swap + vm.swappiness=10 │
└─────────────────────────────────────────────────────────────┘
1核1G 不是不能用,是不能直接用默认配置。以上 10 项调整全部在软件层面完成,零硬件成本,动态站点 QPS 从 60 提升到 330,延迟从 1.45 秒降到 310 毫秒。
如果你的 VPS 还在用出厂默认配置,现在就去改——5 分钟,速度翻倍。