經(jīng)常使用 WordPress 進(jìn)行開(kāi)發(fā)的朋友可能都知道,WordPress 有一套自己的計(jì)劃任務(wù)系統(tǒng)(WP-Cron),這套 Cron 系統(tǒng)和 Linux 的 Cron系統(tǒng)有很大的區(qū)別。
- Linux Cron:只要到達(dá)指定時(shí)間且系統(tǒng)運(yùn)行中,任務(wù)就會(huì)自動(dòng)執(zhí)行。
- WP-Cron:需要依賴網(wǎng)站訪問(wèn)才能觸發(fā),具體流程是:
- WordPress 將計(jì)劃任務(wù)信息存儲(chǔ)在數(shù)據(jù)庫(kù)中
- 當(dāng)用戶訪問(wèn)網(wǎng)站時(shí),系統(tǒng)檢查是否有待執(zhí)行的任務(wù)
- 如果存在需要執(zhí)行的任務(wù),則立即執(zhí)行
WordPress 定時(shí)任務(wù)計(jì)劃系統(tǒng)的問(wèn)題
WP Cron 的這種設(shè)計(jì)帶來(lái)了兩個(gè)主要問(wèn)題:
- 執(zhí)行時(shí)間不準(zhǔn)確:任務(wù)不一定在設(shè)定的確切時(shí)間執(zhí)行
- 可能錯(cuò)過(guò)執(zhí)行:如果在計(jì)劃時(shí)間內(nèi)沒(méi)有用戶訪問(wèn)網(wǎng)站,任務(wù)就不會(huì)被觸發(fā)
這種機(jī)制對(duì)于訪問(wèn)量大的網(wǎng)站影響較小,但對(duì)于需要準(zhǔn)時(shí)執(zhí)行的關(guān)鍵任務(wù)來(lái)說(shuō)并不適用。
一個(gè)真實(shí)的定時(shí)任務(wù)例子
假設(shè)我們需要實(shí)現(xiàn)這樣一個(gè)功能:每小時(shí)檢查特定目錄下的 CSV 文件,如果文件存在則導(dǎo)入到數(shù)據(jù)庫(kù)并刪除文件。使用普通的 WP-Cron 可能會(huì)導(dǎo)致任務(wù)無(wú)法按時(shí)執(zhí)行。
優(yōu)化方案:結(jié)合系統(tǒng) Cron 觸發(fā) WP Cron
我們知道,操作系統(tǒng)的計(jì)劃任務(wù),只要設(shè)置好了,到了時(shí)間就會(huì)自動(dòng)執(zhí)行,沒(méi)有其他的附加條件。所以要解決這個(gè)問(wèn)題,我們需要設(shè)置一個(gè)操作系統(tǒng)級(jí)別的任務(wù)計(jì)劃,模擬用戶定時(shí)訪問(wèn)站點(diǎn)。
為了避免操作系統(tǒng)的任務(wù)計(jì)劃和 WordPress 的任務(wù)計(jì)劃起沖突,造成重復(fù)執(zhí)行的問(wèn)題,我們先禁用 WordPress 的任務(wù)計(jì)劃系統(tǒng),然后使用?wp_schedule_event 安排我們的任務(wù)計(jì)劃操作。
1. 禁用 WP Cron 定時(shí)任務(wù)系統(tǒng)
在 wp-config.php 中, 添加下面的定義代碼:
define('DISABLE_WP_CRON', true);
2. 添加事項(xiàng)操作
首先,定義一個(gè)每小時(shí)指定的動(dòng)作,指定一個(gè)需要執(zhí)行的函數(shù)名稱,在下面的例子中,就是 update_db_hourly。
add_action( 'my_hourly_event', 'update_db_hourly' );
3. 添加定時(shí)任務(wù)函數(shù)
現(xiàn)在,定義 update_db_hourly 函數(shù)使用 WordPress 調(diào)度事項(xiàng)。如果是在插件中,我們可以在插件激活時(shí),調(diào)度任務(wù), (同時(shí),不要忘了在插件禁用時(shí)移除調(diào)度):
public static function activate() {
wp_schedule_event( time(), 'hourly', 'my_hourly_event' );
}
public static function deactivate() {
wp_clear_scheduled_hook('my_hourly_event');
}
最后,定義執(zhí)行實(shí)際的操作函數(shù),也就是第一步指定的 update_db_hourly。
public function update_db_hourly() {
// 1. 檢查是否有文件
// 2. 如果有、導(dǎo)入,然后刪除
// 3. 如果沒(méi)有,不執(zhí)行任何操作
}
4. 設(shè)置計(jì)劃任務(wù)
基于 cPanel 或其他面板的主機(jī)一般都有自定義計(jì)劃任務(wù)的界面,我們可以通過(guò) Web 界面非常方便的設(shè)置計(jì)劃任務(wù),有些服務(wù)器沒(méi)有在圖形界面,只能通過(guò)訪問(wèn)命令行,通過(guò)命令來(lái)設(shè)置計(jì)劃任務(wù)。Linux 系統(tǒng)可以通過(guò) crontab -e 來(lái)編輯計(jì)劃任務(wù),加入以下指令到計(jì)劃任務(wù)文件、然后保存即可。
*/15 * * * * wget -q -O - http://yourdomain.com/wp-cron.php?doing_wp_cron
或者使用 curl 也可以達(dá)到同樣的目的。
*/15 * * * * curl --silent "https://yourdomain.com/wp-cron.php?doing_wp_cron" > /dev/null 2>&1
上面的設(shè)置將每 15 分鐘執(zhí)行一次,向 WordPress 站點(diǎn)發(fā)出請(qǐng)求,從而啟動(dòng)我們?cè)O(shè)置好的計(jì)劃任務(wù)。
設(shè)置計(jì)劃任務(wù)并不是一個(gè)非常復(fù)雜的過(guò)程,但是除非您熟悉 WordPress 定時(shí)任務(wù)系統(tǒng)的工作原理,使用的時(shí)候就會(huì)遇到我們上面提到的問(wèn)題。希望本文能夠幫助你了解 WordPress 是如何處理計(jì)劃任務(wù)的,并在需要的時(shí)候正確設(shè)置 WordPress 的任務(wù)計(jì)劃。
除了常見(jiàn)的定時(shí)操作,我們還可以在 WordPress 計(jì)劃任務(wù)系統(tǒng)的基礎(chǔ)上實(shí)現(xiàn)異步 PHP 和定時(shí)任務(wù)隊(duì)列,有需要的朋友可以點(diǎn)擊鏈接了解詳情。


