使用 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 協議》,轉載必須註明作者和本文連結