最近在整理 WordPress 服务器配置时,发现一个很常见的问题:一台 2 核 2G 的服务器,网站刚搭好没多久,内存占用就已经接近 80%,偶尔打开后台还会出现卡顿。
很多人的第一反应是服务器配置太低,或者直接重启 PHP、MySQL。重启以后内存确实降下来了,但过几个小时又会涨回去。
说白了,重启只是把现场清空,并没有解决问题。
WordPress 内存过高,可能是 PHP-FPM 进程太多,也可能是 MySQL 参数不合理、插件后台任务堆积,甚至只是 Linux 把空闲内存拿去做了缓存。
所以,看到内存占用 80% 先别急着升级服务器。真正要做的,是先判断这部分内存到底被谁用了。
下面把这次完整的排查思路记录下来。
2 核 2G 运行 WordPress 够不够用?

先说结论。
如果只是一个普通博客、企业站或者流量不大的内容网站,2 核 2G 运行 WordPress 通常够用。
前提是服务器配置合理,没有安装一堆高消耗插件,也没有大量动态请求。
一台常规的 WordPress 服务器,主要运行以下几个服务:
- Nginx 或 Apache
- PHP-FPM
- MySQL 或 MariaDB
- WordPress 程序
- Redis、面板和监控服务
- Linux 系统自身进程
真正容易占内存的,一般不是 Nginx,而是 PHP-FPM 和 MySQL。
如果使用宝塔、1Panel 等服务器面板,还要算上面板程序、监控程序和计划任务的消耗。2G 内存看起来不少,但每个服务占一点,很快就没有多少剩余空间了。
所以问题不一定是 WordPress 本身太重,而是服务器上的所有服务加在一起超过了承受范围。
Linux 内存占用高不等于内存不足
排查的第一步,不是修改配置,而是执行:
free -h
输出结果一般会包含:
total
used
free
shared
buff/cache
available
很多人只看 used,发现已经用了 1.7G,就觉得服务器要爆了。
其实不能这么判断。
Linux 会主动把暂时不用的内存拿来做文件缓存。这样下次读取文件时速度更快。如果程序需要更多内存,系统可以释放其中一部分缓存。
相比 free,更值得关注的是 available。
如果 available 还有几百 MB,而且服务器没有使用大量 Swap,也没有发生 OOM,那么内存占用看起来很高,不一定是故障。
真正需要警惕的是下面几种情况:
available长期低于 100MB- Swap 使用量持续增加
- 网站频繁出现 502 或 504
- PHP-FPM、MySQL 经常自动重启
- 系统日志出现 OOM Killer
- 后台操作时服务器明显卡顿
也就是说,我们要判断的不是“内存用了多少”,而是“内存还够不够程序继续正常运行”。
WordPress 内存过高怎么查是哪个进程导致的?
先执行下面的命令,按照内存占用对进程进行排序:
ps aux --sort=-%mem | head -20
也可以使用:
top
如果服务器安装了 htop,查看起来会更直观:
htop
重点关注以下进程:
php-fpm
mysqld
mariadbd
nginx
redis-server
如果前十名里大部分都是 PHP-FPM,问题很可能出在 PHP 进程池、WordPress 插件或者动态请求上。
如果 MySQL 一个进程占用了五六百 MB,则要继续检查数据库配置。
如果内存主要被系统缓存占用,而 available 仍然充足,就不需要急着清理。
还可以查看 PHP-FPM 进程的内存:
ps -ylC php-fpm --sort:rss
不同系统的进程名称可能不一样,也可以使用:
ps aux | grep php-fpm
ps aux | grep -E "mysql|mariadb"
这一步的目标很简单:先找到主要内存消耗者,再决定修改什么。
不然上来就改 WordPress 配置、装缓存插件,本质上都是碰运气。
检查服务器是否已经触发 OOM

OOM 是 Out Of Memory 的缩写,也就是系统已经没有足够的内存可以分配。
当物理内存和 Swap 都不够时,Linux 可能会强制杀掉某个进程。被杀掉的经常是 PHP-FPM 或 MySQL,因为它们占用的内存比较多。
执行:
dmesg -T | grep -i -E "oom|killed process"
或者:
journalctl -k | grep -i -E "oom|killed process"
如果日志里出现类似信息:
Out of memory
Killed process
php-fpm
mysqld
那就不是普通的“内存占用高”,而是服务器真的发生过内存耗尽。
这时要重点排查三个问题:
- PHP-FPM 是否创建了过多进程;
- 单个 PHP 请求是否消耗了过多内存;
- MySQL 是否占用了过大的常驻内存。
不要只通过增加 Swap 来掩盖问题。Swap 可以兜底,但不能替代正常的内存配置。
PHP-FPM 进程太多是最常见的问题
WordPress 的 PHP 页面需要交给 PHP-FPM 处理。
当访问量增加,或者某个插件不断发起后台请求时,PHP-FPM 会创建更多工作进程。每个进程都要占用内存。
假设单个 PHP-FPM 进程平均占用 60MB,同时运行 15 个进程,就是:
60MB × 15 = 900MB
对于一台只有 2G 内存的服务器来说,这已经非常高了。
PHP-FPM 常见的进程管理模式有三种:
static:固定开启指定数量的进程dynamic:根据请求数量动态增减进程ondemand:有请求时才创建进程,空闲后自动结束
对于访问量不大的 2 核 2G WordPress 网站,我更倾向于使用 ondemand,或者配置得比较保守的 dynamic。
PHP-FPM 配置文件的位置因系统和 PHP 版本而异,常见路径包括:
/etc/php/8.2/fpm/pool.d/www.conf
/etc/php-fpm.d/www.conf
可以先查找:
find /etc -name "www.conf" 2>/dev/null
重点检查这些参数:
pm = ondemand
pm.max_children = 6
pm.process_idle_timeout = 10s
pm.max_requests = 500
这里的数字不能照抄,需要根据服务器实际情况调整。
pm.max_children 决定最多允许同时运行多少个 PHP 工作进程。设置太大,访问量一上来就可能直接吃光内存;设置太小,则可能导致请求排队。
一个比较实用的计算方法是:
分配给 PHP-FPM 的内存 ÷ 单个 PHP 进程平均内存
例如给 PHP-FPM 预留 500MB,单个进程平均占用 60MB:
500 ÷ 60 ≈ 8
考虑到还要留出安全空间,可以把 pm.max_children 设置为 6 左右,然后根据访问情况继续观察。
修改后要检查配置并重启 PHP-FPM:
php-fpm -t
systemctl restart php8.2-fpm
具体服务名称需要根据当前 PHP 版本修改。
不要把 PHP memory_limit 当成服务器内存
这是很多 WordPress 新手最容易搞混的地方。
WordPress 中常见下面两个配置:
define('WP_MEMORY_LIMIT', '128M');
define('WP_MAX_MEMORY_LIMIT', '256M');
PHP 配置文件里还有:
memory_limit = 256M
这些参数限制的是单次 PHP 请求最多可以使用多少内存,不是整个服务器只使用这么多内存。
如果 memory_limit 设置成 512M,并不代表 PHP 总共只占用 512M。
假设同时有 6 个 PHP 进程,每个进程都接近 300MB,理论上就可能消耗接近 1.8G 内存。
这也是为什么直接把 WordPress 内存限制调到 512M,并不一定能解决问题,反而可能让小服务器更快触发 OOM。
对于普通 WordPress 网站,前台内存限制可以先从 128M 开始。后台编辑器、导入程序或 WooCommerce 确实需要更多内存时,再根据实际错误适当增加。
如果日志中出现:
Allowed memory size exhausted
才说明某个 PHP 请求碰到了单次内存上限。
这时应该先查清楚是哪个插件、页面或任务消耗了大量内存,而不是无上限地往上加。
WordPress 插件导致内存过高怎么排查?
PHP-FPM 参数限制的是结果,插件和主题问题才可能是原因。
WordPress 中比较容易消耗内存的插件类型包括:
- 页面可视化编辑器
- 自动备份插件
- 安全扫描插件
- 数据统计插件
- 相关文章插件
- 图片压缩插件
- 数据导入和采集插件
- WooCommerce 及其扩展
- 站内搜索和索引插件
如果问题是在安装某个插件以后出现的,可以先停用最近安装的插件。
有 WP-CLI 的情况下,可以查看插件状态:
wp plugin list
临时停用全部插件:
wp plugin deactivate --all
然后逐个恢复:
wp plugin activate 插件名称
每恢复一个插件,就观察一次内存和 PHP-FPM 进程。
当然,正式网站不要在访问高峰期直接停用全部插件。更稳妥的方法是先做备份,再在测试环境中排查。
如果停用全部插件后内存明显下降,说明问题大概率就在插件里。
如果插件全部停用后问题依然存在,可以暂时切换到 WordPress 默认主题,继续排除主题中的自定义代码、查询循环和后台任务。
开启 WordPress 调试日志查异常
可以在 wp-config.php 中加入或修改以下配置:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
错误日志通常会写入:
wp-content/debug.log
重点查找:
- PHP Fatal error
- Allowed memory size exhausted
- 数据库查询错误
- 重复执行的函数
- 某个插件不断产生警告
- 请求超时
生产网站排查结束后,建议关闭调试模式,避免日志文件不断增长:
define('WP_DEBUG', false);
还要检查 debug.log 的文件大小。有些网站问题解决了,但日志没有关闭,最后几 GB 的日志又把磁盘写满了。这种坑不算高级,但确实很常见。
MySQL 内存占用过高怎么优化?
MySQL 本身就需要使用一部分内存作为缓存,所以看到 MySQL 占用两三百 MB 不一定异常。
真正要检查的是它有没有超过这台服务器合理的承受范围。
先登录数据库查看主要参数:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Max_used_connections';
其中,innodb_buffer_pool_size 是比较关键的参数。
它用于缓存 InnoDB 表和索引。设置得大,可以减少磁盘读取;但在 2G 内存服务器上设置得过大,就会挤压 PHP-FPM 和系统的可用空间。
如果数据库和 WordPress 部署在同一台 2G 服务器上,可以先从 256MB 到 384MB 这个范围观察,而不是直接套用大型数据库服务器的配置。
例如:
[mysqld]
innodb_buffer_pool_size = 256M
max_connections = 50
这只是保守参考值,不是所有网站都必须这样设置。
如果网站并发很低,实际只使用几个数据库连接,就没有必要把 max_connections 设置成几百。因为部分 MySQL 内存会随着连接数量增加而增长。
修改数据库配置前一定要备份,并先确认当前配置文件位置。修改后重启服务,再检查错误日志,避免因为参数写错导致 MySQL 无法启动。
WordPress 数据库还要检查 autoload 数据
有些网站 MySQL 内存和 PHP 内存一起升高,原因不是文章太多,而是 wp_options 表中的自动加载数据太大。
WordPress 每次请求都会加载 autoload 数据。如果某个插件向里面写入了大量配置、缓存或者已经失效的数据,那么每次访问页面都要把这部分内容读出来。
可以先查询自动加载数据的大致体积。不同 WordPress 版本的字段结构可能有差异,常见查询方式为:
SELECT SUM(LENGTH(option_value)) AS autoload_size
FROM wp_options
WHERE autoload = 'yes';
再查体积较大的记录:
SELECT option_name, LENGTH(option_value) AS option_size
FROM wp_options
WHERE autoload = 'yes'
ORDER BY option_size DESC
LIMIT 20;
如果表前缀不是 wp_,需要替换成自己网站使用的前缀。
发现大记录以后,不要直接删除。
先判断它属于哪个插件,确认插件是否仍在使用,再做好数据库备份。很多插件卸载以后会留下配置数据,但也有一些记录是网站正常运行所必需的。
数据库优化不是“看到大表就删”,而是先弄清楚数据是谁写入的。
WP-Cron 后台任务可能让 PHP 进程堆积
WordPress 默认使用 WP-Cron 执行计划任务。
它不是真正的系统定时任务,而是在用户访问网站时检查有没有到期任务。如果某个任务执行很慢,下一批请求又继续触发,就可能出现任务重叠。
常见任务包括:
- 定时发布文章
- 备份网站
- 安全扫描
- 发送邮件
- 清理缓存
- WooCommerce 队列任务
- 插件同步和数据抓取
可以使用 WP-CLI 查看计划任务:
wp cron event list
如果确认要改用 Linux Crontab,可以在 wp-config.php 中禁用页面访问触发:
define('DISABLE_WP_CRON', true);
然后添加系统定时任务,例如每 5 分钟执行一次:
*/5 * * * * cd /网站目录 && wp cron event run --due-now >/dev/null 2>&1
也可以请求 wp-cron.php,但要根据网站环境设置正确路径和执行用户。
需要注意,禁用 WP-Cron 后必须配置替代任务。不然定时文章、邮件和插件任务都可能不再正常运行。
排查恶意请求和异常爬虫
有时候服务器配置没问题,插件也没有明显异常,但 PHP-FPM 进程还是不断增加。
这时要检查访问日志。
Nginx 日志常见位置是:
/var/log/nginx/access.log
先查看近期请求:
tail -n 200 /var/log/nginx/access.log
统计访问次数较多的 IP:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
还要重点关注这些地址:
/wp-login.php
/xmlrpc.php
/wp-admin/admin-ajax.php
/wp-json/
admin-ajax.php 并不一定是攻击请求,很多正常插件也依赖它。但如果它每秒被请求多次,就要继续检查是前端插件、后台任务,还是恶意流量导致的。
xmlrpc.php 如果没有使用需求,可以通过 Web 服务器规则或安全插件限制访问。
对于公开网站,可以使用 CDN、防火墙、登录保护和请求限速降低动态请求压力。
缓存只能减少正常访问造成的 PHP 请求,挡不住所有恶意流量。请求已经大量打到 PHP-FPM 后,再好的页面缓存也可能扛不住。
2G 服务器要不要增加 Swap?
我的看法是:要有,但不要依赖。
先检查当前 Swap:
swapon --show
free -h
如果服务器完全没有 Swap,可以创建一个 1G 左右的 Swap 文件作为兜底:
fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
写入 /etc/fstab,让它重启后自动启用:
/swapfile none swap sw 0 0
还可以适当降低系统使用 Swap 的积极程度:
sysctl vm.swappiness=10
需要永久生效,可以写入系统的 sysctl 配置文件。
Swap 的作用是防止内存短时间耗尽时,系统立即杀死 PHP 或 MySQL 进程。
但是 Swap 使用的是磁盘,速度远低于物理内存。如果网站已经长期大量使用 Swap,服务器通常会明显变慢。
所以,Swap 是安全垫,不是额外赠送的内存。
2 核 2G WordPress 可以参考的优化方向
经过前面的排查,一台普通 2 核 2G WordPress 服务器可以优先从下面几个方向调整:
- PHP-FPM 使用
ondemand或保守的dynamic模式; - 根据单个 PHP 进程内存限制
pm.max_children; - 不盲目把 PHP
memory_limit调到 512M; - 控制 MySQL Buffer Pool 和最大连接数;
- 删除不再使用的高消耗插件;
- 检查
wp_options自动加载数据; - 使用系统 Cron 代替访问触发的 WP-Cron;
- 配置页面缓存,减少重复执行 PHP;
- 限制登录、XML-RPC 和异常爬虫请求;
- 保留适量 Swap,防止突发 OOM。
至于 Redis,不是所有 2G 服务器都必须安装。
Redis 对查询较多的网站有帮助,但它自己也要占内存。如果只是一个访问量很低的博客,页面缓存带来的效果可能比对象缓存更直接。
工具不是装得越多越好。对于小服务器来说,每增加一个常驻服务,都要考虑它到底解决了什么问题。
WordPress 内存优化前后怎么对比?
修改配置以后,不要只看当时的内存。
至少观察几个小时,最好覆盖一次正常访问高峰,并记录:
| 检查项目 | 优化前 | 优化后 |
|---|---|---|
| 系统 available 内存 | 按实际记录 | 按实际记录 |
| PHP-FPM 进程数量 | 按实际记录 | 按实际记录 |
| 单个 PHP 进程内存 | 按实际记录 | 按实际记录 |
| MySQL 内存占用 | 按实际记录 | 按实际记录 |
| Swap 使用量 | 按实际记录 | 按实际记录 |
| 后台响应时间 | 按实际记录 | 按实际记录 |
| 502/504 次数 | 按实际记录 | 按实际记录 |
最好每次只修改一类参数。
如果同时改 PHP-FPM、MySQL、缓存和插件,最后内存降下来了,你也不知道到底是哪项调整起了作用。
排查问题最怕的不是不会改配置,而是改得太多,失去了对比依据。
2 核 2G WordPress 内存过高的最终判断
回到最开始的问题:2 核 2G 服务器运行 WordPress,内存占用 80% 是不是太高?
不一定。
如果 available 内存仍然充足,没有频繁使用 Swap,也没有 OOM 和 502 错误,那么这部分内存可能只是正常缓存。
如果可用内存持续下降,PHP-FPM 进程不断增加,Swap 越用越多,那才说明服务器存在真正的内存压力。
整个排查顺序可以概括成:
先看 available
再查进程
接着查 OOM
然后排查 PHP-FPM
再检查插件、MySQL 和 WP-Cron
最后处理异常流量并配置 Swap
不要一看到 WordPress 内存过高就重启服务器,也不要上来就升级配置。
先把资源消耗的来源找出来。
如果只是 PHP-FPM 参数开得太大,或者一个插件不断执行后台任务,升级到 4G 服务器也只是让问题晚一点出现。
服务器优化这件事,本质上不是把内存占用压得越低越好,而是在有限的配置里,让 PHP、MySQL 和系统之间保持一个稳定的平衡。仅此而已。