THINKPHP6 佇列
1.安裝think-queue
composer require topthink/think-queue
2.配置訊息佇列,將config/queue.php將’default’ => ‘sync’改為’default’ => ‘redis’,使用Redis驅動
如選擇database,需建立表
CREATE TABLE `prefix_jobs` ( `id` int(11) NOT NULL AUTO_INCREMENT, `queue` varchar(255) NOT NULL, `payload` longtext NOT NULL, `attempts` tinyint(3) unsigned NOT NULL, `reserve_time` int(10) unsigned DEFAULT NULL, `available_time` int(10) unsigned NOT NULL, `create_time` int(10) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3.建立生產者
class Index extends BaseController
{
/**
* 單任務
*/
public function singleTask()
{
//當前任務將由哪個類來負責處理
$jobHandlerClassName = 'app\job\Job1';
//業務資料 物件需要手動轉序列化
$jobData = ['ts' => time()];
//佇列名稱
$jobQueueName = "createOrderJob";
//入佇列,later延時傳送,單位秒。push立即傳送
$isPushed = Queue::later(2, $jobHandlerClassName, $jobData,$jobQueueName);
//$isPushed = Queue::push( $jobHandlerClassName , $jobData , $jobQueueName );
// database 驅動時,返回值為 1|false ; redis 驅動時,返回值為 隨機字串|false
if( $isPushed !== false ){
echo '執行成功';
}else{
echo '執行失敗';
}
//php think queue:listen --queue createOrderJob 執行佇列
//nohup php think queue:listen --queue createOrderJob & 不以守護程式執行
}
/**
* 多工
*/
public function multiTask(){
$taskType = $_GET['taskType'];
switch ($taskType) {
case 'taskA':
$jobHandlerClassName = 'app\job\MultiTask@taskA';
$jobDataArr = ['a' => '1'];
$jobQueueName = "multiTaskJobQueue";
break;
case 'taskB':
$jobHandlerClassName = 'app\job\MultiTask@taskB';
$jobDataArr = ['b' => '2'];
$jobQueueName = "multiTaskJobQueue";
break;
default:
break;
}
$isPushed = Queue::push($jobHandlerClassName, $jobDataArr, $jobQueueName);
if ($isPushed !== false) {
echo("the $taskType of MultiTask Job has been Pushed to ".$jobQueueName ."<br>");
}else{
echo "push a new $taskType of MultiTask Job Failed!";
}
}
}
4.建立消費者
單任務
class Job1
{
public function fire(Job $job, $data)
{
//業務處理程式碼,具體不貼出來了
$isJobDone = $this->jobDone($data);
//執行成功刪除
if($isJobDone){
$job->delete();
print("任務已經被執行成功並且刪除");
}else{
$job->release(3); //$delay為延遲時間 表示該任務延遲3秒後再執行
print("任務3s後再次被執行");
}
//通過這個方法可以檢查任務重試了幾次
if ($job->attempts() > 3) {
print("Job has been retried more than 3 times!");
$job->delete();
}
}
public function failed($data)
{
// ...任務達到最大重試次數後,失敗了
}
private function jobDone($data){
Log::write('這是資料 ' . json_encode($data));
return true;
}
多工
class MultiTask{
public function taskA(Job $job,$data){
$isJobDone = $this->_doTaskA($data);
if ($isJobDone) {
$job->delete();
print("Info: TaskA of Job MultiTask has been done and deleted"."\n");
}else{
$job->release(3);
print("任務3s後再次被執行");
}
if ($job->attempts() > 3) {
print("Job has been retried more than 3 times!");
$job->delete();
}
}
public function taskB(Job $job,$data){
$isJobDone = $this->_doTaskB($data);
if ($isJobDone) {
$job->delete();
print("Info: TaskB of Job MultiTask has been done and deleted"."\n");
}else{
$job->release(3);
print("任務3s後再次被執行");
}
if ($job->attempts() > 3) {
print("Job has been retried more than 3 times!");
$job->delete();
}
}
private function _doTaskA($data) {
print("Info: doing TaskA of Job MultiTask "."\n");
return true;
}
private function _doTaskB($data) {
print("Info: doing TaskB of Job MultiTask "."\n");
return true;
}
}
5.執行
php think queue:listen --queue createOrderJob
我的檔案目錄
在database 模式下,2.7.1 和 2.7.2 中的重發邏輯是先刪除原來的任務,然後插入一個新的任務。2.7.3 中的重發時機是直接更新原任務。
而在redis 模式下,3種重發都是先刪除再插入。
不管是哪種重發方式,重發之後,任務的已嘗試次數會在原來的基礎上 +1 。
此外,消費者類中需要注意,如果 fire() 方法中可能丟擲異常,那麼如果不需要自動重發的話, 請在丟擲異常之前將任務刪除 $job->delete() ,以免產生bug。 如果需要自動重發的話,請直接丟擲異常,不要在 fire() 方法中又手動使用 $job->release() , 這樣會導致該任務被重發兩次,產生兩個一樣的新任務。
相關文章
- 佇列、阻塞佇列佇列
- 佇列-單端佇列佇列
- 佇列 和 迴圈佇列佇列
- 【佇列】【懶排序】佇列Q佇列排序
- 陣列模擬佇列 以及佇列的複用(環形佇列)陣列佇列
- 佇列 手算到機算 入門 佇列 迴圈佇列佇列
- 圖解--佇列、併發佇列圖解佇列
- 單調佇列雙端佇列佇列
- 佇列佇列
- RabbitMQ 訊息佇列之佇列模型MQ佇列模型
- Kafka 延時佇列&重試佇列Kafka佇列
- Java版-資料結構-佇列(陣列佇列)Java資料結構佇列陣列
- C語言 簡單的佇列(陣列佇列)C語言佇列陣列
- 稀疏陣列、佇列陣列佇列
- 阻塞佇列一——java中的阻塞佇列佇列Java
- 07-主佇列和全域性佇列佇列
- 佇列(楊輝三角)——鏈式佇列佇列
- synchronized 中的同步佇列與等待佇列synchronized佇列
- 動畫佇列動畫佇列
- java佇列Java佇列
- 佇列,棧佇列
- 映象佇列佇列
- 棧、佇列佇列
- 貓狗佇列佇列
- iOS 佇列iOS佇列
- 阻塞佇列佇列
- 棧-佇列佇列
- netcore下RabbitMQ佇列、死信佇列、延時佇列及小應用NetCoreMQ佇列
- 佇列的一種實現:迴圈佇列佇列
- 三、資料結構演算法-棧、佇列、優先佇列、雙端佇列資料結構演算法佇列
- 【資料結構】佇列(順序佇列、鏈佇列)的JAVA程式碼實現資料結構佇列Java
- Python佇列的三種佇列實現方法Python佇列
- Java版-資料結構-佇列(迴圈佇列)Java資料結構佇列
- 訊息佇列系列一:訊息佇列應用佇列
- JDK QUEUE佇列JDK佇列
- 閒話佇列佇列
- laravel佇列demoLaravel佇列
- Laravel佇列使用Laravel佇列