使用 Laravel 訊息佇列要注意的問題

紙牌屋弗蘭克發表於2017-12-12

使用 Laravel 的訊息佇列處理非同步任務,Redis 作為佇列資料庫,Supervisor 監控指令碼異常中斷並自動重啟,這是 Laravel 處理佇列任務的標準流程,但是實際中可能還會出現各種各樣的問題,為了保證系統可靠性,還要注意幾個問題。

一、執行失敗重試次數設定

一定要設定任務執行失敗重試次數,避免無限失敗重試,超過重試次數 Laravel 會預設寫到失敗任務表中,也可以自己寫執行失敗後續處理邏輯。

php artisan queue:work redis --tries=3

需要先執行以下命令建立資料表:

php artisan queue:failed-table

php artisan migrate

二、程式異常的處理

有時候程式執行過程會發生異常,比如依賴其他介面,請求 HTTP 介面超時等等,如果不捕捉異常,那麼當前這個佇列就會中斷不能繼續執行下去,比如給 10000 個使用者推送內容,需要依賴介面推送,如果中間的請求掛了就會影響到後面的推送。

這裡的異常是指程式執行過程中發生的異常,不是指常駐程式掛掉,程式異常不一定導致常駐程式中斷,況且程式中斷有 Supervisor 監控並重啟。

如捕獲異常程式碼片段:

try {
    $r = $client->request('POST', '', [
        'query' => [
            'client_name'     => 'filemail',
            'client_version'  => '1.0',
            'client_sequence' => 0,
            'uid'             => 692934013,//119481237
            'r'               => 1508312484,
        ],
        'body'  => \GuzzleHttp\json_encode($body),
    ]);
    $result = $r->getBody()->getContents();
    $result = json_decode($result, true);
    if ($result['result'] == 0) {
        info("sendMail fail:" . json_encode($result));
        $this->pushLog($task['id'], $task['mail_id'], implode(',', $userIds), json_encode($result), 0);
    } else {
        Log::warning("sendMail fail:" . json_encode($result));
        $this->pushLog($task['id'], $task['mail_id'], implode(',', $userIds), json_encode($result), $result['result']);
    }
} catch (RequestException $e) {
    Log::warning('RequestException' . $e->getMessage());
} catch (Exception $e) {
    Log::emergency('Exception' . $e->getMessage());
}

三、修改程式碼記得重啟 Supervisor

最後一點,修改了處理佇列的程式,記得要重啟 Supervisor,否則指令碼不會生效。

後續還有的話會繼續補充,原文連結:https://blog.tanteng.me/2017/12/laravel-qu...

參考連結

Laravel 官方文件 Queue 佇列:

https://learnku.com/docs/laravel/5.5/queues

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

相關文章