禁用WP-Cron并使用服务器定时任务

如果您的WordPress网站运行迟缓,或服务器CPU突然飙升,WP-Cron很可能是罪魁祸首。WordPress内置了一套伪定时任务系统——wp-cron.php——它通过在每次页面加载时触发来执行计划任务(备份、邮件、更新检查等)。对于高流量网站,这意味着每小时会产生数百个额外的PHP进程。解决方法很简单:禁用WP-Cron,用真实的服务器定时任务替代它。

核心问题:WP-Cron并不按时间表运行,而是在每次HTTP请求时触发。每小时访问量1,000次的网站,即使计划任务只需运行一次,wp-cron.php也可能被触发多达1,000次。

第一步:在wp-config.php中禁用WP-Cron

打开您的wp-config.php文件(位于WordPress根目录),在/* That's all, stop editing! */注释之前添加以下代码:

define('DISABLE_WP_CRON', true);

这将阻止WordPress在每次页面加载时启动内部定时任务。在完成第二步设置真实定时任务之前,计划事件将不会运行。

请勿跳过第二步。禁用WP-Cron后,在配置好真实定时任务之前,WordPress不会执行任何计划任务。备份、更新通知和定时发布的文章都将暂时停止运行。

第二步:在DirectAdmin上设置真实定时任务

  1. 登录DirectAdmin → 高级功能 → 定时任务(Cron Jobs)
  2. 将执行频率设置为每5分钟(推荐)或高流量网站每1分钟
  3. 输入以下命令:
wget -q -O /dev/null "https://yourdomain.com/wp-cron.php?doing_wp_cron" >/dev/null 2>&1

如果 wget 不可用,可使用curl:

curl -s "https://yourdomain.com/wp-cron.php?doing_wp_cron" >/dev/null 2>&1

将yourdomain.com替换为您的实际域名。末尾的>/dev/null 2>&1会屏蔽所有输出,避免每5分钟收到一封定时任务邮件。

Crontab 时间表参考

Cron 表达式 含义
*/1 * * * *每1分钟
*/5 * * * *每5分钟(推荐)
0 * * * *每整点运行一次
0 0 * * *每天午夜运行

第三步:使用WP Crontrol插件验证

WP Crontrol(WordPress.org上的免费插件)可让您查看、编辑、删除和手动运行WordPress中的所有定时事件。设置好服务器定时任务后:

  1. 在插件 → 安装插件中安装WP Crontrol
  2. 前往工具 → 定时事件(Cron Events)
  3. 检查各事件的"下次运行"时间——服务器定时任务触发后,时间应正确更新
  4. 您也可以在此界面添加或删除自定义定时事件

配置前先了解Cron表达式

无论您使用DirectAdmin的定时任务界面还是原始crontab,都需要了解Cron表达式的语法。Cron表达式包含五个字段:分钟、小时、日期、月份和星期几。每个字段可以是数字、星号(表示每次)或步进值(如*/5表示每5个单位)。

表达式含义适用场景
*/5 * * * *每5分钟大多数WordPress网站(推荐)
*/1 * * * *每1分钟需要精确定时的高流量网站
0 * * * *每整点运行极低流量的网站
0 2 * * *每天凌晨2:00每日备份任务
0 0 * * 0每周日午夜每周维护任务

不确定表达式是否正确?使用AsiaGB免费的Cron表达式生成器,无需记忆语法即可生成和验证Cron表达式。

禁用WP-Cron后的常见问题

禁用WP-Cron并设置服务器定时任务后,如果配置有误,可能会遇到以下问题:

定时发布的文章没有发布

原因:PHP二进制文件路径错误导致服务器定时任务无法运行。通过SSH使用which php确认正确路径。部分服务器需要使用php8.1或php8.2而非单纯的php。

# 查找正确的PHP路径
which php
# 或检查可用版本
ls /usr/bin/php*

定时任务邮件塞满收件箱

在定时任务命令末尾添加> /dev/null 2>&1以丢弃所有输出,或在crontab第一行设置MAILTO=""全局屏蔽所有邮件:

MAILTO=""
*/5 * * * * php /home/username/domains/example.com/public_html/wp-cron.php > /dev/null 2>&1

备份插件未按计划运行

UpdraftPlus和BackWPup等插件依赖WordPress Cron触发自身的定时备份。当服务器定时任务每5分钟运行一次wp-cron.php时,这些插件任务会在其配置时间自动执行——无需额外配置。服务器定时任务只需确保WordPress定时任务队列被可靠地处理即可。

专业建议:将繁重的备份任务安排在凌晨1:00至4:00之间(流量最低时段)。这样可以保持CPU使用率可预测,并确保备份任务在不与访客请求竞争资源的情况下顺利完成。

WordPress多站点网络中的WP-Cron

在WordPress多站点安装中,禁用WP-Cron的方式相同,但有一个关键区别:无论有多少个子站点,您只需做一处修改并设置一个定时任务。

使用前后对比:性能影响

对比项目 WP-Cron(默认) 服务器定时任务
触发方式每次页面加载精确每5分钟
对页面加载的影响给所有请求增加PHP额外开销对页面加载零影响
可靠性需要访客触发无流量时也能运行
CPU使用率高流量时占用高可预测,开销低

禁用WP-Cron后保护wp-cron.php

切换到服务器定时任务后,wp-cron.php文件仍可通过HTTP公开访问。这暴露了一个潜在的攻击面:任何人都可以发送HTTP请求触发您的定时任务队列,或通过大量请求尝试发起拒绝服务攻击。解决方法是在保持服务器端定时任务正常工作的同时,阻止公众对该文件的访问。

在Apache(.htaccess)中阻止访问

在WordPress根目录的.htaccess文件中添加以下内容:

# 阻止公开访问wp-cron.php
<Files wp-cron.php>
  Order allow,deny
  Deny from all
  Allow from 127.0.0.1
</Files>

这样只允许本地(127.0.0.1)访问wp-cron.php,当定时任务通过PHP CLI而非HTTP运行时,这已完全够用。

在Nginx中阻止访问

# 在Nginx server块中添加
location = /wp-cron.php {
    allow 127.0.0.1;
    deny  all;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

注意:如果您的定时任务命令使用curl或wget而非PHP CLI,请将命令改为直接调用本地地址:curl -s http://127.0.0.1/wp-cron.php?doing_wp_cron -H "Host: yourdomain.com"——这样可以避免触发自身的防火墙拦截。

使用WP-CLI执行定时任务

如果您的主机支持WP-CLI(WordPress命令行界面),它提供了比直接运行wp-cron.php更强大的替代方案。命令wp cron event run --due-now只处理真正到期的事件,并提供更好的错误可见性:

# WP-CLI定时任务命令(将php路径替换为WP-CLI运行器)
*/5 * * * * /usr/local/bin/wp cron event run --due-now \
  --path=/home/username/domains/example.com/public_html \
  --quiet > /dev/null 2>&1
方法优势局限性
PHP CLI (wp-cron.php)适用于任何主机,配置简单必须使用正确的PHP二进制路径
WP-CLI详细日志,便于调试需要服务器上已安装WP-CLI
curl / wget(HTTP方式)无需Shell访问权限HTTP额外开销,IP必须被允许

定时任务不运行的故障排查

如果已设置服务器定时任务,但WordPress任务仍未按计划运行,请先检查定时任务守护进程日志——大多数故障源于PHP路径错误、文件权限不足或缺少环境变量。

# 在CentOS / AlmaLinux上查看Cron日志
tail -50 /var/log/cron

# 在Ubuntu / Debian上查看Cron日志
grep CRON /var/log/syslog | tail -50

# 在Shell中手动测试定时任务命令
php /home/username/domains/example.com/public_html/wp-cron.php
echo $?   # 应返回0(成功)

如果命令在终端中正常运行,但在定时任务中静默失败,原因几乎总是PATH环境变量——定时任务环境的PATH比交互式Shell要窄得多。解决方法是为所有二进制文件指定绝对路径:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*/5 * * * * /usr/bin/php8.2 /home/username/domains/example.com/public_html/wp-cron.php > /dev/null 2>&1

长期维护:迁移后的检查事项

从WP-Cron切换到真实服务器定时任务后,请将以下检查项纳入网站日常维护流程,确保长期运行正常:

最终验证:设置完成后等待10至15分钟,然后打开WP Crontrol(工具 → 定时事件)。如果所有事件的"下次运行"时间戳都在按您设定的间隔正确更新,则服务器定时任务运行完全正常。

支持DirectAdmin定时任务的WordPress主机

AsiaGB主机服务配备DirectAdmin,提供完整的定时任务管理功能。无需命令行即可设置服务器端定时任务。起价500泰铢/年。

查看主机方案 →