WordPress WP-Cron 漏跑排程排查紀錄:用重試佇列把發布自動化留成證據

WordPress 的排程系統很方便:排程文章、備份、通知信、同步工作與外掛維護任務,都可能靠 WP-Cron 觸發。問題是 WP-Cron 不是傳統系統 cron;它通常要等網站有請求時才被觸發。如果網站流量低、快取層擋住觸發、主機背景工作不穩,或外掛事件執行太久,就可能出現「文章到了時間卻沒發布」或「自動化任務延遲好幾小時」的狀況。
我會把 WP-Cron 漏跑當成一條自動化證據鏈,而不是只按一次「立即發布」就結案。這篇整理一份比較安全的排查紀錄寫法:先保存症狀,再檢查事件清單、外部 cron、重試佇列、log 與最終發布結果,讓下次遇到相同問題時可以知道是哪一層失效。
先記錄漏跑的是哪一種排程
不要一開始就停用外掛或清掉所有 cron event。先把漏跑範圍寫清楚:是單篇排程文章、批次同步、寄信任務、備份任務,還是所有排程都延遲。
WP-Cron symptom record
- affected task: scheduled post publish
- expected run time: 2026-08-25 09:00 +08:00
- observed state: still scheduled at 09:18
- affected scope: one post / all scheduled posts / plugin jobs
- manual publish used before evidence: no
這段紀錄可以避免排查到一半忘記原始狀態。尤其是內容站,排程文章延遲不只影響發布時間,也可能影響首頁最新文章、sitemap 更新、社群自動分享與搜尋引擎抓取節奏。
用 WP-CLI 檢查事件,不要只看後台畫面
WordPress 後台可能只顯示文章還在排程中,但不一定告訴你 cron event 是否真的存在。可以用 WP-CLI 留下事件層的證據:
wp cron event list \
--fields=hook,next_run_gmt,recurrence \
--format=table
wp post list \
--post_status=future,publish \
--fields=ID,post_title,post_status,post_date \
--format=table
我會把觀察結果寫成可比對的紀錄,而不是只說「看起來有排程」:
Cron event evidence
- publish_future_post hook: exists
- next_run_gmt: 2026-08-25 01:00:00
- target post status: future
- current server time: 2026-08-25 01:18:00 GMT
如果 publish_future_post 或外掛自訂 hook 根本不存在,問題可能是排程建立失敗;如果事件存在但一直沒被觸發,就要往外部 cron、流量觸發、快取或主機背景工作排查。
分開檢查內建 WP-Cron 與外部系統 Cron
很多維運團隊會把 DISABLE_WP_CRON 設為 true,再由系統 cron 定期打 /wp-cron.php。這通常比較穩,但也多了一層要驗證的設定。排查時要分開記錄,不要混在一起。
wp config get DISABLE_WP_CRON
curl -I 'https://www.example.com/wp-cron.php?doing_wp_cron'
wp cron test
如果是外部 cron,維護紀錄至少要保存頻率與最近執行狀態:
External cron evidence
- DISABLE_WP_CRON: true
- system cron frequency: every 5 minutes
- wp-cron.php response: 200
- last successful trigger: 2026-08-25 09:15 +08:00
- owner: hosting panel / server crontab / managed service
這裡不要把主機帳密、控制台 token 或完整私有路徑寫進文章與 repo。需要保留的是真正能幫助判斷的狀態、時間與回應碼。
建立重試佇列,而不是無限手動補跑
排程漏跑時,最危險的修法是「看到一筆就手動補一筆」,因為很快就不知道哪些任務已執行、哪些失敗、哪些重複發送。比較好的做法是把需要補跑的任務放進一個簡單的重試紀錄,至少包含 hook、目標內容、嘗試次數與結果。
Retry queue record
- task: publish scheduled post
- target: post ID 123
- first missed at: 2026-08-25 09:00 +08:00
- retry 1: triggered by wp cron event run
- retry 2: not needed
- final state: published
- duplicate side effects checked: email / webhook / social share
如果需要手動觸發 due events,也要把命令與結果分開保存:
wp cron event run --due-now
wp post get 123 \
--fields=ID,post_title,post_status,post_date_gmt \
--format=json
對於會寄信、發 webhook、同步 CRM 或推送社群的任務,補跑前更要確認是否具備冪等性。排程文章補發布通常可控;通知信或第三方同步重複執行,可能造成讀者或客戶收到多次訊息。
檢查快取與發布後的公開證據
WP-Cron 成功執行,不代表讀者立刻看到新內容。內容站還要檢查快取、sitemap、首頁與文章 canonical。排程發布後,我通常會留下這幾個公開層證據:
curl -I 'https://www.example.com/new-post-slug/'
curl -I 'https://www.example.com/sitemap.xml'
curl -I 'https://www.example.com/'
維護紀錄可以寫成:
Publish verification
- article URL: 200
- content-type: text/html
- canonical URL: /new-post-slug/
- sitemap contains slug: yes
- homepage latest list refreshed: yes
- cache header after publish: no-store / HIT refreshed / PURGE completed
這比只看 WordPress 後台顯示 publish 更完整。尤其是有 CDN、全頁快取或靜態化外掛的網站,後台已發布但前台仍回舊 HTML,是另一個常見問題。
建議保留的回滾與決策紀錄
WP-Cron 排查常牽涉外掛、主機排程與快取策略,因此每一步都要有回滾點。可以在維護紀錄中保留這些欄位:
Rollback notes
- config changed: external cron frequency from 15 min to 5 min
- plugin setting changed: none
- cache purged: only article URL and homepage
- rollback path: restore previous cron interval
- sensitive data stored in repo: no
如果最後需要調整外部 cron 頻率,我會把它當成維運決策,而不是隨手改設定。理由可能是「排程文章需要 5 分鐘內發布」、「舊頻率 15 分鐘造成社群同步延遲」或「主機限制不允許更高頻率」。這些理由未來都會影響成本、效能與監控策略。
小結:把排程自動化變成可驗證系統
WP-Cron 漏跑不只是 WordPress 小毛病,它會影響內容營運節奏、通知流程與讀者看到的最新資訊。排查時如果只靠直覺手動補發布,很容易修好眼前一篇,卻留下下一次更難追的自動化風險。
比較穩的做法是把它拆成幾層:症狀、事件清單、外部 cron、重試佇列、公開頁面、sitemap 與回滾紀錄。當每一層都有 status、時間與輸出證據,WP-Cron 就不再是黑盒子,而會變成網站經營中可監控、可維護、可復盤的一部分。