
文章目录
结论先行: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 本身无状态持久化风险。
如何确认真的执行了
不能只看“没报错”。三层验证:
- 事件层:
wp cron event list看 next_run 是否按 recurrence 前进。 - 执行层:在回调里写日志到
wp-content/cron-debug.log,或用 Query Monitor 看 HTTP 请求。 - 业务层:比如定时发文,检查
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 步

- 跑
wp cron event list确认是否有过期未执行事件。 - 检查 wp-config.php 是否误开 DISABLE_WP_CRON 或相反未开。
- 用 crontab -l 看系统级是否配置了 */5 分钟任务。
- 对卡死 hook 执行
wp cron event delete再重排。 - 用日志表或
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 多站点该不该用 的部署建议。
立即动作清单
- 在 wp-config.php 写入 define(‘DISABLE_WP_CRON’, true) 并验证语法。
- 为服务器添加 */5 分钟 crontab 执行 wp cron event run –due-now。
- 对卡死任务用 wp cron event delete 清理并重新 schedule。
- 建一张 cron_log 表或写文件日志,确认业务真执行。
- 把上述步骤写进部署清单,避免新环境重蹈覆辙。
定时任务不稳别硬扛,交给系统 cron 才是正解。需要落地到生产环境,可看我们的 WordPress 开发服务,也欢迎读 技术栏目首页 更多排障笔记。
