首页 › 博客 › 文章

WordPress 定时任务不执行?WP-Cron 的真实问题与替代方案

WordPress 定时任务不执行?WP-Cron 的真实问题与替代方案

结论先行:WP-Cron 不执行时,先在 wp-config.php 加 define(‘DISABLE_WP_CRON’, true),再用服务器 crontab 每 5 分钟请求 wp-cron.php 或执行 WP-CLI 的 cron event run;验证看 wp_options 里 cron 数组的 schedule 是否被消费、以及任务日志表。做对了的表现是:无访问也有任务按点执行,且 site health 不再报 scheduled event 延迟。

靠访问触发的机制缺陷

WP-Cron 不是系统级守护进程,而是每次前端或后端请求(包括 REST、admin-ajax)时,在 wp-cron.php 或 wp-includes/cron.php 里由 spawn_cron() 检查是否有到期事件。若站点无流量,任务永远不触发;流量低时也会严重偏移。2026 年的 WordPress 6.7/6.8 依然保留这套逻辑,官方未改为常驻。

典型现象:定时发布文章没发、wp_scheduled_auto_draft_delete 没清草稿、WooCommerce 的 woocommerce_cleanup_sessions 不跑。用下面命令看当前事件:

wp cron event list
wp cron event list --fields=hook,next_run,recurrence

若 next_run 已过期且长期不动,就是没被触发。另一缺陷是同一请求里多个到期任务会串行执行,某个慢任务会堵住后面的。修复方向只有一个:别靠访问触发,交给系统 cron。相关背景可看 WordPress 官方 WP-Cron 文档。

DISABLE_WP_CRON 与系统 cron

在 wp-config.php 里关闭内置触发:

define('DISABLE_WP_CRON', true);

这行必须放在 /* That's all, stop editing! */ 之前。关闭后,WP 不再在请求里 spawn,改由系统 cron 驱动。两种驱动方式:

方式 A:crontab 请求 URL

适合无法用 WP-CLI 的环境。每 5 分钟一次:

*/5 * * * * curl -s -o /dev/null https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

注意 & 要转义为 & 若在 HTML 外写文件时用原样;上面代码块里已按 XML/HTML 转义为 & 的实体写法仅在网页场景需要,crontab 文件里直接写 & 即可。

获取报价

邮箱 + 需求 + 预算区间,24 小时内回复报价。

方式 B:crontab 调用 WP-CLI(推荐)

更稳,不走 HTTP 层:

*/5 * * * * cd /var/www/html && wp cron event run --due-now >> /var/log/wp-cron.log 2>&1

路径按实际站点根目录改。若用 WordPress 企业网站开发 交付的容器环境,通常已预置该条目。验证:等 10 分钟后执行 wp cron event list,看 next_run 是否推进。

踩坑:DISABLE_WP_CRON 写错位置、常量名拼错、或用了缓存插件把 wp-cron.php 缓存了都会失效。回退方法:注释掉 define,临时恢复访问触发,再用 wp cron test(部分版本)或手动触发确认。

任务卡死的处理

任务卡死常见原因:回调抛致命错误、外部 API 超时、或 set_time_limit(0) 下无限循环。表现为某个 hook 一直 running,后续同队列任务不执行。先查:

wp cron event run --due-now --debug
wp option get cron

在 wp_options 的 cron 里能看到每个事件的 args 与 schedule。若某事件卡住,先清掉再重排:

wp cron event delete hook_name
wp cron event schedule hook_name --recurrence=hourly

若是代码 bug,在 mu-plugins 或主题里用 set_error_handler 捕获,或给回调加 try/catch 与超时。2026 年主流做法是任务幂等+短超时。清理后回退:若删错,重新 wp cron event schedule 即可,WP-Cron 本身无状态持久化风险。

如何确认真的执行了

不能只看“没报错”。三层验证:

  1. 事件层:wp cron event list 看 next_run 是否按 recurrence 前进。
  2. 执行层:在回调里写日志到 wp-content/cron-debug.log,或用 Query Monitor 看 HTTP 请求。
  3. 业务层:比如定时发文,检查 wp_posts 里 post_date 与 post_status 是否变化。

更硬的做法是加一张日志表:

function my_log_cron($hook) {
  global $wpdb;
  $wpdb->insert($wpdb->prefix . 'cron_log', ['hook' => $hook, 'run_at' => current_time('mysql')]);
}
add_action('my_hourly_task', function() { my_log_cron('my_hourly_task'); });

然后 wp db query "SELECT * FROM wp_cron_log ORDER BY run_at DESC LIMIT 10;"。若查得到且时间连续,就是真执行了。失败回退:把日志表 truncate 重来,或换回系统 cron 方式 B。

排查流程:从现象到修复的 5 步

排查流程:从现象到修复的 5 步
  1. 跑 wp cron event list 确认是否有过期未执行事件。
  2. 检查 wp-config.php 是否误开 DISABLE_WP_CRON 或相反未开。
  3. 用 crontab -l 看系统级是否配置了 */5 分钟任务。
  4. 对卡死 hook 执行 wp cron event delete 再重排。
  5. 用日志表或 wp option get cron 验证 next_run 推进。

该流程覆盖 90% 的 WP-Cron 不执行场景。若服务器是共享主机无 crontab 权限,只能用 WordPress 主机怎么选 里提到的升级 VPS 方案,或用外部监控服务打 URL。

常见问题

WP-Cron 不执行一定是配置错了吗?

不一定。先区分是“没触发”还是“触发了但回调失败”。用 event list 与日志表两层验证,再决定改配置还是改代码。

关了 DISABLE_WP_CRON 后任务还是不动?

检查 crontab 是否生效、WP-CLI 路径是否在 cron 的 PATH 里,以及 WP-CLI 常用命令 是否可用。多数是 cd 路径错导致命令没跑。

多站点下 WP-Cron 要单独配吗?

要。每个子站有自己的 wp-config 或需用 network 级 cron;可参 WordPress 多站点该不该用 的部署建议。

立即动作清单

  1. 在 wp-config.php 写入 define(‘DISABLE_WP_CRON’, true) 并验证语法。
  2. 为服务器添加 */5 分钟 crontab 执行 wp cron event run –due-now。
  3. 对卡死任务用 wp cron event delete 清理并重新 schedule。
  4. 建一张 cron_log 表或写文件日志,确认业务真执行。
  5. 把上述步骤写进部署清单,避免新环境重蹈覆辙。

定时任务不稳别硬扛,交给系统 cron 才是正解。需要落地到生产环境,可看我们的 WordPress 开发服务,也欢迎读 技术栏目首页 更多排障笔记。

参考资料与延伸阅读

WPDaiwei

WPDaiwei-专业Wordpress网站定制开发提供商

需要 WordPress 开发服务?

24 小时内免费出方案与报价,国内国外都接单。

QQ