在開發(fā) WordPress 應(yīng)用程序的時(shí)候,我們偶爾會(huì)進(jìn)行一些比較耗時(shí)的操作,比如同時(shí)給 1000 個(gè)訂閱用戶發(fā)送郵件,如果這么多郵件通過(guò)一個(gè)任務(wù)同時(shí)發(fā)送,很可能會(huì)導(dǎo)致 PHP 進(jìn)程執(zhí)行超時(shí)而退出,進(jìn)而引起部分任務(wù)執(zhí)行失敗,這個(gè)時(shí)候,我們需要使用任務(wù)隊(duì)列來(lái)分批執(zhí)行任務(wù)。WordPress 并沒(méi)有內(nèi)置的任務(wù)隊(duì)列實(shí)現(xiàn),我們只能自己添加或者借助第三方庫(kù)實(shí)現(xiàn),今天為大家介紹的就是一個(gè)在 WordPress 中實(shí)現(xiàn)任務(wù)隊(duì)列的庫(kù):WP Queue。
WP Queue 的工作原理和安裝方法
和大多數(shù)任務(wù)隊(duì)列一樣,WP Queue 是基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)的一個(gè)任務(wù)隊(duì)列系統(tǒng)。有了各個(gè)任務(wù)隊(duì)列系統(tǒng),我們只需要需要把任務(wù)推送到任務(wù)隊(duì)列里面,然后讓 WP Queue 按照設(shè)置好的規(guī)則逐個(gè)執(zhí)行。安裝 WP Queue 庫(kù)的方法很簡(jiǎn)單,直接在主題或插件項(xiàng)目的根目錄執(zhí)行 composer require a5hleyrich/wp-queue 即可。
由于 WP Queue 只是一個(gè) PHP 庫(kù),而不是一個(gè)插件,在使用之前,我們需要先安裝任務(wù)隊(duì)列需要的數(shù)據(jù)表到 WordPress 數(shù)據(jù)庫(kù)中。執(zhí)行下列語(yǔ)句把數(shù)據(jù)表安裝到 WordPress 數(shù)據(jù)庫(kù)中即可,如果是在 phpMyAdmin 中直接執(zhí)行,需要先把 {$wpdb->prefix} 換成對(duì)應(yīng)的 WordPress 數(shù)據(jù)表前綴,一般是wp_。
CREATE TABLE {$wpdb->prefix}queue_jobs (
id bigint(20) NOT NULL AUTO_INCREMENT,
job longtext NOT NULL,
attempts tinyint(3) NOT NULL DEFAULT 0,
reserved_at datetime DEFAULT NULL,
available_at datetime NOT NULL,
created_at datetime NOT NULL,
PRIMARY KEY (id)
CREATE TABLE {$wpdb->prefix}queue_failures (
id bigint(20) NOT NULL AUTO_INCREMENT,
job longtext NOT NULL,
error text DEFAULT NULL,
failed_at datetime NOT NULL,
PRIMARY KEY (id)
如果我們?cè)?WordPress主題或插件中使用 WP Queue 庫(kù),在主題或插件初始化的時(shí)候,我們可以調(diào)用 wp_queue_install_tables() 輔助函數(shù)來(lái)安裝數(shù)據(jù)表。
使用 WP Queue 實(shí)現(xiàn)任務(wù)隊(duì)列
把任務(wù)添加到任務(wù)隊(duì)列之前,我們需要先實(shí)現(xiàn)一個(gè)任務(wù)類,任務(wù)類應(yīng)該擴(kuò)展 WP_Queue\Job 類,通常只需要包含一個(gè)任務(wù)處理方法,當(dāng)隊(duì)列執(zhí)行任務(wù)的時(shí)候會(huì)調(diào)用該方法,任務(wù)所需的數(shù)據(jù)應(yīng)傳遞給該類的構(gòu)造函數(shù)并設(shè)置公開訪問(wèn)屬性。從隊(duì)列中獲取任務(wù)后,我們可以訪問(wèn)這些數(shù)據(jù)。下面是一個(gè)示例任務(wù)類:
<?php
use WP_Queue\Job;
class Subscribe_User_Job extends Job {
/**
* @var int
*/
public $user_id;
/**
* Subscribe_User_Job constructor.
*
* @param int $user_id */
public function __construct( $user_id ) {
$this->user_id = $user_id;
}
/**
* 處理任務(wù)邏輯
*/
public function handle() {
$user = get_user_by( 'ID', $this->user_id );
// 處理用戶...
}
}
調(diào)度任務(wù)隊(duì)列中的任務(wù)
創(chuàng)建了任務(wù)類之后,我們可以用下面的方法把任務(wù)添加到任務(wù)隊(duì)列中,以便任務(wù)隊(duì)列按照隊(duì)列順序執(zhí)行:
wp_queue()->push( new Subscribe_User_Job( 12345 ) );
我們可以在添加任務(wù)到隊(duì)列的時(shí)候,通過(guò)一個(gè)附加參數(shù)來(lái)設(shè)置任務(wù)隊(duì)列延遲執(zhí)行。比如,通過(guò)下面的方法添加的任務(wù)將會(huì)延遲 1 小時(shí)執(zhí)行。
wp_queue()->push( new Subscribe_User_Job( 12345 ), 3600 );
定制執(zhí)行任務(wù)隊(duì)列
任務(wù)隊(duì)列需要一個(gè)任務(wù)調(diào)度器來(lái)執(zhí)行,通過(guò)下面的方法可以安排一個(gè)計(jì)劃任務(wù)來(lái)調(diào)度執(zhí)行任務(wù)隊(duì)列中的任務(wù)。該任務(wù)隊(duì)列在 WordPress 的計(jì)劃任務(wù)系統(tǒng)上實(shí)現(xiàn)。
wp_queue()->cron();
此外,我們還可以指定任務(wù)隊(duì)列中的任務(wù)失敗的時(shí)候,重新嘗試執(zhí)行的次數(shù)。
wp_queue()->cron( 3 );
通過(guò)使用 WP Queue 類,在 WordPress主題或插件中執(zhí)行大量重復(fù)且耗時(shí)操作的時(shí)候,我們就可以使用任務(wù)隊(duì)列系統(tǒng)來(lái)保證操作的可靠性和系統(tǒng)的性能了。如果你需要一個(gè)實(shí)際的參考示例,可以查看一下 WP?Image Processing Queue 圖像處理庫(kù)的代碼,看一個(gè)這個(gè)庫(kù)是怎么使用?WP Queue 添加計(jì)任務(wù)隊(duì)列的。


