Laravel8的重複執行佇列無效

bluememory發表於2022-05-11

最近業務需求需要用到佇列,我就使用框架自帶的佇列了,使用mysql驅動程式,jobs和failed_jobs表都有了,現在就是如果佇列執行失敗,可以再次執行,最多5次。
參考文件最大嘗試次數我的程式碼是這樣的:

<?php

namespace App\Jobs;


use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;

/**
 * 出單任務
 *
 * Class PolicyOrder
 * @package App\Jobs
 */
class PolicyOrder implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $params;

    /**
     * 任務嘗試次數
     *
     * @var int
     */
    public $tries = 5;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($params)
    {
        $this->params = $params;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

            //發起出單請求
            $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
            $response = json_decode($response->body(), true);
            print_r($response);
    }

}

通過:php artisan queue:listen –queue=policyOrderQueue執行,成功執行了進來,但是就執行一次,我不知道哪裡問題,文件就這麼一句話,當我覺得少了什麼。

經過一些搜尋,通過$this->release()達到效果:

public function handle()
    {
        try {

                //發起出單請求
                $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
                $response = json_decode($response->body(), true);
                print_r($response);
                if ($response['status'] != 0) { //失敗的情況
                    throw new \Exception($response['statusInfo']);
                } else {
                    //更新訂單號
                    UserTrip::where(['id' => $this->params['user_trip_id']])
                        ->update(['order_no' => $response['data']['orderno']]);
                }

        } catch (\Exception $e) {
            $this->release(5); //5秒後重新放入佇列,繼續出單【配合$tries = 5使用】
            Log::error($e->getMessage());
        }
    }

上面程式碼正常,其實文件也說拋異常,我試過【只拋不要去捕獲,捕獲了就沒有效果了】:

public function handle()
    {
                //發起出單請求
                $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
                $response = json_decode($response->body(), true);
                print_r($response);
                if ($response['status'] != 0) { //失敗的情況
                    throw new \Exception($response['statusInfo']);
                } else {
                    //更新訂單號
                    UserTrip::where(['id' => $this->params['user_trip_id']])
                        ->update(['order_no' => $response['data']['orderno']]);
                }
    }

上面這種會把異常資訊存到failed_jobs表的exception欄位:

下面程式碼也可以:

 public function handle()
    {
                //發起出單請求
                $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
                $response = json_decode($response->body(), true);
               // print_r($response);
                if ($response['status'] != 0) { //失敗的情況
                    $this->release(5);
                } else {
                    //更新訂單號
                    $res = UserTrip::where(['id' => $this->params['user_trip_id']])
                        ->update(['order_no' => $response['data']['orderno']]);

                }
            }
        } 
    }

如果還是需要捕獲異常也可以這樣寫:

public function handle()
    {
        try {

                //發起出單請求
                $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
                $response = json_decode($response->body(), true);
                print_r($response);
                if ($response['status'] != 0) { //失敗的情況
                    throw new \Exception($response['statusInfo']);
                } else {
                    //更新訂單號
                    UserTrip::where(['id' => $this->params['user_trip_id']])
                        ->update(['order_no' => $response['data']['orderno']]);
                }

        } catch (\Exception $e) {
            Log::error($e->getMessage());
            throw $e; //拋異常,可以重新放入佇列
        }
    }

在catch裡面繼續throw

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章