章: 第4章: 非同期処理とイベント駆動
外部APIへの接続が一時的に失敗したとき、ジョブがそのまま消えてしまう――これはジョブの 失敗設計がない 状態で起きる定番の事故です。「たまに失敗する」と「常に失敗する」の間にある状態を放置すると、運用後に大きな手戻りを召います。
LaravelのQueueには tries や backoff といった 失敗制御の仕組み が備わっています。ジョブ作成時にこれらを設定することで、一時障害を彼らで待つ自後のくなる地設計を実現できます。
なぜQueue失敗設計が重要なのか
tries と backoff を設定せずになりじみな再試行を任せると次の問題が起きます。
- 外部APIが復旧する前に最大試行回数に達し、ジョブが失敗テーブルに落ちる
- 短時間に大量の再試行が発生し、障害復旧中のサーバーを加速させる(サンダーヘルド)
failed()メソッドを定義せず、障害発生をチームが知れない
チェックポイント:
backoffに数列を渡すと再試おきに待機時間を増やせます(Exponential Backoff)。外部APIへの再試時は必ず使いましょう。
tries/backoffの設定指針
| 設定項目 | 推奨値 | 理由 |
$tries |
3~5回 | 無限ループを防ぐ最低限必要 |
$backoff |
[10, 30, 60, 120] |
復旧待機の時間を容許する |
$timeout |
60~300秒 | 處理とチェックが走る冥 |
failed() |
ログ・通知 | 失敗時にチームへ通知 |
実装例
<?php
class SyncInventory implements ShouldQueue
{
public int $tries = 5;
public array $backoff = [10, 30, 60, 120];
public function handle(InventoryClient $client): void
{
$client->sync();
}
public function failed(\Throwable $e): void
{
logger()->error('在庫同期に失敗', ['error' => $e->getMessage()]);
}
}
まとめ & 次のステップ
triesとbackoffはジョブ作成時に必ず設定する習慣をつけるfailed()で失敗通知を実装することで、失敗ジョブを流すのを防ぐ$maxExceptionsで不再試行の例外タイプを指定できるphp artisan queue:failedで失敗ジョブ一覧を確認し、retryで再実行できる
次回は 第10回: HorizonでQueue監視 で、Queue処理の状態をダッシュボードで可視化する方法を学びます。