為啥要學?
還不是因為自己菜,隊列之前的接觸的也少,正好這2天沒啥事,就想好好了解一下隊列的基本使用,至少以后別人問起來,我也能大膽的說自己用過啊!
notice:queue安裝,自行composer就行,不過要注意版本,因為現在已經出到TP6了
首先我們需要先創建隊列,不贅述了,直接上代碼
支持的隊列方式有很多:db,redis等等,這里使用的redis隊列
如果你安裝成功在你tp5.1的config文件夾下會有一個queue.php的配置文件,里面去改redis的配置就行
config/queue.php
'connector' => 'Redis', // Redis 驅動
'expire' => 60, // 任務的過期時間,默認為60秒; 若要禁用,則設置為 null
'default' => 'default', // 默認的隊列名稱
'host' => '', // redis 主機ip
'port' => 6379, // redis 端口
'password' => '', // redis 密碼
'select' => 15, // 使用哪一個 db,默認為 db0
'timeout' => 0, // redis連接的超時時間
'persistent' => false, // 是否是長連接
創建隊列--數據入隊
app\index\controller\JobTest
<?php
/**
* Created by PhpStorm.
* User: mayn
* Date: 2019/10/12
* Time: 16:47
*/
namespace app\index\controller;
use think\Queue;
class JobTest
{
public function actionWithHelloJob(){
// 1.當前任務將由哪個類來負責處理。
// 當輪到該任務時,系統將生成一個該類的實例,並調用其 fire 方法
//$jobHandlerClassName = 'application\index\job\Hello'; //這里千萬不要寫成這個,不然將會失敗
$jobHandlerClassName = 'app\index\job\Hello';
// 2.當前任務歸屬的隊列名稱,如果為新隊列,會自動創建
$jobQueueName = "helloJobQueue";
// 3.當前任務所需的業務數據 . 不能為 resource 類型,其他類型最終將轉化為json形式的字符串
// ( jobData 為對象時,需要在先在此處手動序列化,否則只存儲其public屬性的鍵值對)
$jobData = [ 'ts' => time(), 'bizId' => uniqid() , 'a' => 1 ] ;
$isPushed = Queue::push( $jobHandlerClassName , $jobData, $jobQueueName );
// database 驅動時,返回值為 1|false ; redis 驅動時,返回值為 隨機字符串|false
if( $isPushed !== false ){
echo date('Y-m-d H:i:s') . " a new Hello Job is Pushed to the MQ"."<br>";
}else{
echo 'Oops, something went wrong.';
}
}
}
隊列處理--出隊
app\index\job\Hello
<?php
/**
* Created by PhpStorm.
* User: mayn
* Date: 2019/10/12
* Time: 16:53
*/
namespace app\index\job;
use think\Db;
use think\queue\job;
class Hello
{
/**
* @param job $job 當前的任務對象
* @param $data 發布任務時自定義的數據
*/
public function fire( job $job,$data ){
$isJobDone = $this->doHelloJob($data);
if ($isJobDone) {
//如果任務執行成功, 記得刪除任務
print_r("<info>Hello Job has been done and deleted"."</info>\n");
$job->delete();
}else {
if ($job->attempts() > 3) {
//通過這個方法可以檢查這個任務已經重試了幾次了
print_r("<warn>Hello Job has been retried more than 3 times!" . "</warn>\n");
$job->delete();
// 也可以重新發布這個任務
//print("<info>Hello Job will be availabe again after 2s."."</info>\n");
//$job->release(2); //$delay為延遲時間,表示該任務延遲2秒后再執行
}
}
}
public function failed($data){//發送失敗寫入系統日志
cache('failtime',time());
}
/**
* 有些消息在到達消費者時,可能已經不再需要執行了
* @param array|mixed $data 發布任務時自定義的數據
* @return boolean 任務執行的結果
*/
private function checkDatabaseToSeeIfJobNeedToBeDone($data){
return true;
}
/**
* 根據消息中的數據進行實際的業務處理
* @param array|mixed $data 發布任務時自定義的數據
* @return boolean 任務執行的結果
*/
private function doHelloJob($data) {
// 根據消息中的數據進行實際的業務處理...
file_put_contents('aaaa.txt',$data,FILE_APPEND);
/*$info = [
'user_name' => $data['bizId'],
];
$res = Db::name('user')->insert($info);
if( $res ){
return true;
}else{
return false;
}*/
}
執行:
入隊:項目域名/index.php/index/job_test/actionWithHelloJob
數據處理:php think queue:work --queue helloJobQueue (單次執行) ||
php think queue:listen --queue helloJobQueue(一直會監聽)