WordPress 的定时发布、备份、缓存清理、邮件发送和插件后台任务,很多都依赖 WP-Cron。它和 Linux 的 cron 不同:默认情况下,WordPress 会在有人访问网站时检查是否存在到期任务,再通过一次回环请求启动 wp-cron.php。网站访问少、回环请求失败、任务本身报错,都会造成“已经设置了定时任务,但一直没有执行”。
排查时先确认问题停在哪一层:计划事件没有注册、事件已经到期却没有触发,还是任务已被触发但执行失败。直接反复点击插件里的“立即运行”,可能暂时推动队列,却不一定能修复下一次执行。

先分清 WP-Cron 和插件队列
WordPress 核心使用 WP-Cron 管理计划事件。插件可以通过它安排一次性或周期任务,例如定时发布文章、检查更新和清理临时数据。
WooCommerce、邮件插件和部分备份插件还会使用 Action Scheduler。它有自己的待处理、运行中、失败和完成状态,但队列启动通常仍依赖 WP-Cron、异步请求或单独配置的队列运行器。因此,后台看到大量 pending 任务时,既要检查队列,也要确认负责唤醒队列的 WP-Cron 是否正常。
常见现象可以这样判断:
- 定时文章偶尔延迟,刷新网站后执行:多半是访问触发不足;
- 所有计划任务都不动:检查
DISABLE_WP_CRON、回环请求和wp-cron.php; - 只有某个插件的任务失败:检查对应 Hook、插件日志和依赖服务;
- WP-Cron 正常,但 Action Scheduler 的
pending持续增加:检查队列运行器、失败动作和单个任务耗时; - 每隔几分钟重复执行同一批任务:检查系统 Cron 与默认 WP-Cron 是否重复触发,以及插件是否反复注册事件。
检查 WP-Cron 是否被关闭
先备份 wp-config.php。如果服务器已安装 WP-CLI,可以读取常量:
wp config get DISABLE_WP_CRON --type=constant --path=/var/www/html
返回 true 表示页面访问不会再自动启动 WP-Cron。这项设置本身没有问题,但服务器上必须已经存在系统计划任务。常见故障是迁移网站时复制了下面这行配置,却没有迁移原服务器的 crontab:
define( 'DISABLE_WP_CRON', true );
还可以运行官方 WP-CLI 测试命令:
wp cron test --path=/var/www/html
该命令用于测试 WordPress 的 Cron 启动机制。若 WP-Cron 被常量关闭,它会直接报告;若回环请求无法发出,也会返回对应错误。命令成功只能证明启动机制可用,不能证明每个插件任务都能顺利完成。
没有 SSH 权限时,可在“工具 → 站点健康”中查看回环请求和计划事件相关提示。主机面板里若有 WordPress 工具,也要确认它是否自动写入过禁用 WP-Cron 的配置。
列出计划事件,确认是否已经堆积
先查看事件列表,不要立即运行全部任务:
wp cron event list \ --fields=hook,next_run_gmt,next_run_relative,recurrence \ --format=table \ --path=/var/www/html
重点看三类情况:
next_run_relative显示早已到期,说明事件在等待触发或运行器没有推进;- 同一个 Hook 出现大量一次性事件,可能是插件重复注册;
- 完全找不到预期 Hook,说明插件没有成功安排任务,或者事件在插件停用、升级时被移除。
多站点环境要指定站点地址,否则看到的可能不是目标站点:
wp --url=https://site.example cron event list --path=/var/www/html
WordPress 将计划事件保存在数据库的 cron 选项中。需要留档时,可以先导出,而不是直接编辑序列化数据:
wp option get cron --format=json --path=/var/www/html > cron-option-backup.json
手工修改 cron 选项容易破坏时间戳、参数或数组结构。若确认某个 Hook 是插件重复创建,应先查插件版本、任务注册逻辑和官方清理方法,再删除事件。
用单个 Hook 判断“没触发”还是“执行失败”
从列表中选一个可识别、影响较小的 Hook,手动运行:
wp cron event run plugin_example_hook --path=/var/www/html
如果单独运行成功,但事件到期后不会自动执行,问题通常在触发链路。若单独运行也报错,应查看 PHP 错误日志、插件日志、数据库错误和外部 API 响应。
测试期间可以执行所有已经到期的事件:
wp cron event run --due-now --path=/var/www/html
生产站不要一上来使用 --all。积压任务可能包括邮件群发、远程同步、备份压缩和大量数据库写入,集中执行会拉高 CPU、PHP-FPM 进程数和数据库负载。先备份数据库,确认当前流量和资源余量,再分批处理。
回环请求为什么会失败
默认触发流程需要 WordPress 向自己发起非阻塞 HTTP 请求。下面这些配置经常阻断请求:
- 网站启用了 Basic Auth,服务器请求没有认证信息;
- WAF、安全插件或主机防火墙拦截
wp-cron.php; - DNS 仍指向旧服务器,或服务器内部解析到了错误地址;
- HTTPS 证书链、SNI 或强制跳转配置异常;
- 反向代理没有正确传递主机名和 HTTPS 状态;
wp-cron.php被 Nginx、Apache 或 CDN 规则禁止访问;- PHP 无法建立外部 HTTP 连接,或者请求很快超时。
可以从服务器验证入口:
curl -I --max-time 20 'https://example.com/wp-cron.php?doing_wp_cron'
wp-cron.php 通常不会返回可读正文,重点看 DNS、TLS、跳转、认证和 HTTP 状态是否异常。若请求经过 CDN,还要确认边缘防护没有把服务器自身的请求识别为恶意流量。
临时关闭安全插件只能用于短时间定位,操作前应保留配置和访问限制。确认是哪条规则拦截后,应为必要请求建立最小范围的放行规则,不要长期关闭整套防护。
访问量不足时,改用系统计划任务
低访问量网站依赖页面访问触发,任务可能明显晚于计划时间。高访问量网站则可能频繁检查到期事件。需要稳定执行时间时,可以让系统 cron 定期调用 WP-CLI。
先找到 PHP、WP-CLI 和站点的实际路径,并确认运行用户有读取 WordPress 文件、访问数据库及写入必要目录的权限。下面示例每 5 分钟执行一次到期事件,并用 flock 避免上一轮尚未结束时启动新一轮:
*/5 * * * * /usr/bin/flock -n /tmp/example-wp-cron.lock /usr/local/bin/wp --path=/var/www/html cron event run --due-now --quiet >> /home/siteuser/logs/wp-cron.log 2>&1
把路径、日志目录和执行用户替换为实际值。多站点还需要增加 --url=。先手动运行同一条 WP-CLI 命令,确认没有权限或 PHP 环境差异,再写入 crontab。
没有 WP-CLI 时,可以由系统计划任务请求 Cron 入口:
*/5 * * * * /usr/bin/curl -fsS --max-time 60 'https://example.com/wp-cron.php?doing_wp_cron' > /dev/null
确认系统任务已连续运行并能推动到期事件后,再在 wp-config.php 中设置:
define( 'DISABLE_WP_CRON', true );
顺序很重要。先禁用默认 WP-Cron、之后才测试系统任务,会让网站在调试期间完全失去定时触发。回滚时删除或改为 false,并重新检查页面访问触发是否恢复。
Action Scheduler 堆积怎么查
如果插件使用 Action Scheduler,可以先查看总体状态:
wp action-scheduler status --path=/var/www/html
再列出待处理或失败任务:
wp action-scheduler action list --status=pending --per-page=20 --path=/var/www/html wp action-scheduler action list --status=failed --per-page=20 --path=/var/www/html
这些命令只有在站点加载了包含 Action Scheduler CLI 的插件或组件时才可用。观察 Hook 名称、计划时间、参数和所属分组,通常能找到是哪一个插件持续产生任务。
队列积压不等于可以直接清空。待处理任务可能包含订单通知、订阅续费、Webhook、库存同步或邮件发送。先备份数据库,确认业务影响,再按插件文档处理失败动作。直接删除 actionscheduler_actions、actionscheduler_logs 等数据表记录,会丢失任务上下文,也可能让插件状态与队列不一致。
若单个任务一直卡住,可检查 PHP 内存限制、最大执行时间、数据库锁、外部接口超时和插件错误日志。队列能够运行但处理速度跟不上新增速度时,再评估批量大小、并发运行器或专用 WP-CLI 队列进程,调整后持续观察服务器负载。
修复后如何确认已经恢复
完成修改后,至少做一次完整验证:
- 再次运行
wp cron test,确认启动机制没有错误; - 查看
wp cron event list,确认过期时间持续向后推进; - 新建一篇几分钟后发布的测试文章,观察是否按时发布;
- 检查备份、邮件、缓存清理等业务任务是否产生实际结果;
- 查看系统 cron 日志、PHP 日志和插件日志,确认没有重复执行;
- 使用 Action Scheduler 的站点后台或 CLI,确认
pending数量开始下降,failed没有继续增加。
系统 Cron 的执行频率应结合业务需求。定时发布和普通清理通常不需要每分钟运行;订单、订阅或异步邮件对延迟更敏感。频率设得很高也不会修复耗时任务,只会增加重叠和资源竞争的机会。
建议保留的长期检查
站点迁移、域名切换、HTTPS 改造、安全规则调整和 PHP 升级后,都应重新测试 WP-Cron。配置文件与数据库被完整复制时,原站的 DISABLE_WP_CRON、队列记录和旧域名也会一起进入新环境。
日常监控至少覆盖三项:最早过期事件、失败队列数量、最近一次系统 Cron 成功时间。这样能够在定时文章漏发、备份中断或邮件大量积压之前发现问题。发现异常时,先锁定具体 Hook 和失败日志,再决定修复触发器、插件任务还是外部依赖。
参考资料
- WordPress Plugin Handbook:Understanding WP-Cron Scheduling,https://developer.wordpress.org/plugins/cron/understanding-wp-cron-scheduling/
- WordPress Plugin Handbook:Hooking WP-Cron Into the System Task Scheduler,https://developer.wordpress.org/plugins/cron/hooking-wp-cron-into-the-system-task-scheduler/
- WP-CLI Command:
wp cron test,https://developer.wordpress.org/cli/commands/cron/test/ - WP-CLI Command:
wp cron event list,https://developer.wordpress.org/cli/commands/cron/event/list/ - WP-CLI Command:
wp cron event run,https://developer.wordpress.org/cli/commands/cron/event/run/ - WordPress Code Reference:
wp_cron(),https://developer.wordpress.org/reference/functions/wp_cron/ - Action Scheduler:WP-CLI,https://actionscheduler.org/wp-cli/
- Action Scheduler:Performance,https://actionscheduler.org/perf/
资料核验日期:2026 年 9 月 30 日。




