Webアプリケーションを運用していると、「会員登録時のメール送信」「決済完了通知」「外部APIとの大量データ連携」「画像やPDFの圧縮・変換処理」「CSVインポート・エクスポート」など、完了までに数秒から数十秒を要する重い処理が必ず発生します。
これらの処理をユーザーのリクエスト受付中(HTTPリクエスト/レスポンスサイクル内)に同期実行してしまうと、「画面が白く固まる(スピナーが回り続ける)」「Webサーバーの同時接続枠を長時間占有する」「HTTPタイムアウト(504 Gateway Timeout)エラーが発生する」といった深刻なユーザー体験・システム可用性の悪化を引き起こします。
この問題を根本から解決し、爆速のレスポンスを実現する仕組みが Laravelのキュー(Queue)と非同期処理 です。
- キューと非同期処理の基本概念・全体アーキテクチャ
- Redis等の追加インフラ不要!既存DBで動く
databaseキュードライバの設定手順 php artisan make:jobによるJobクラスの作成と適切なトレイト・インターフェースの理解- Jobコンストラクタでのデータ受け渡しと
SerializesModelsの注意点 dispatch(),delay(),onQueue(),dispatchAfterResponse()などの柔軟なキュー投入テクニック- 開発環境での
php artisan queue:workとqueue:listenの起動・使い分け - 本番環境で必須のワーカー常駐化(Supervisor設定・自動復旧・マルチプロセス化)
- 失敗ジョブ(
failed_jobs)の監視・リトライ(queue:retry)・エラーハンドリング - 実践ハンズオン:会員登録時のメール非同期送信実装
- よくあるエラー・トラブルシューティングとベストプラクティス
本記事を順に進めるだけで、初心者から実務エンジニアまで、Laravelのキュー処理を迷わず確実に導入・運用できるようになります。
—
- 1. なぜ非同期キュー処理が必要なのか?仕組みと全体像
- 2. Laravelのキュードライバ一覧と「database」ドライバのメリット
- 3. 【Step 1】databaseキュードライバの導入と初期設定
- 4. 【Step 2】Jobクラスの作成と構造の理解
- 5. 【Step 3】Jobのディスパッチ(キュー投入)パターン集
- 6. 【Step 4】Queue Worker(ワーカー)の起動とローカル開発
- 7. 【Step 5】本番環境でのワーカー常駐化(Supervisor設定)
- 8. 【Step 6】失敗ジョブの監視とエラーハンドリング
- 9. 【実践ハンズオン】会員登録メール非同期送信の一気通貫実装
- 10. よくあるエラー・トラブルシューティングFAQ
- 11. 関連記事・あわせて読みたいLaravel実践ガイド
- 12. まとめ:キューと非同期処理で高パフォーマンスなWebアプリを作ろう
- 関連記事
1. なぜ非同期キュー処理が必要なのか?仕組みと全体像
まずは、非同期キュー処理がどのように動作し、なぜパフォーマンス改善に劇的な効果があるのかを理解しましょう。
同期処理 vs 非同期処理の違い
通常のWeb処理(同期処理)とキューを用いた非同期処理のフローの違いは以下の通りです。
| 項目 | 従来の同期処理(Sync) | キューによる非同期処理(Queue) |
|---|---|---|
| 処理の流れ | リクエスト受付 ➔ 重い処理(メール送信等)を完了するまで待つ ➔ レスポンス返却 | リクエスト受付 ➔ 「Job(依頼票)」をキューに預ける(数ミリ秒) ➔ 即座にユーザーへレスポンス返却 ➔ 裏でワーカーが実行 |
| ユーザー体感速度 | メール送信やAPI通信が終わるまで3〜10秒待たされる | 0.1秒未満で「登録完了」画面が表示される |
| エラー発生時の影響 | メールサーバーがダウンしていると画面が500エラーになる | 画面は正常終了し、バックグラウンドで自動再試行(リトライ)できる |
| サーバー負荷 | アクセス集中時にPHP-FPMのワーカーが枯渇しやすい | Webサーバーとバックグラウンド処理を分離し、負荷を平準化できる |
・同期処理:注文を受けた店員(Webプロセス)が、自分で料理を作り終えてお客さんに配膳するまでレジを離れる状態(レジに行列ができる)。
・非同期キュー処理:店員は「注文伝票(Job)」を厨房のラック(Queue)に差し込んで即座にお客さんへレシートを渡し、奥にいる専任のシェフ(Queue Worker)が順番に料理を作る状態(レジが滞らない)。
—
2. Laravelのキュードライバ一覧と「database」ドライバのメリット
Laravelは多彩なキューバックエンド(ドライバ)を標準サポートしており、設定を切り替えるだけで同じJobコードを異なるインフラ上で実行できます。
| ドライバ名 | 特徴・メリット | 推奨環境・用途 | 前提インフラ |
|---|---|---|---|
sync |
キューに入れずその場で同期実行する(初期デフォルト) | ローカル簡易テスト・単体テスト | なし |
database 🌟 |
MySQL/PostgreSQL/SQLiteのテーブルにジョブを保存。追加サーバー不要・トランザクション連動・手軽で安定 | 小〜中規模本番環境・個人開発・開発環境全般 | 既存のRDBMSのみ |
redis |
インメモリ処理で超高速・秒間数千〜数万件の大量ジョブを処理可能 | 中〜大規模本番環境・Laravel Horizon利用時 | Redisサーバー |
sqs |
AWSのフルマネージドメッセージキュー。サーバーレス・高可用性 | AWSクラウドネイティブな大規模環境 | Amazon SQS |
beanstalkd |
シンプルで軽量なメッセージキュー専用サーバー | 既存のBeanstalkdインフラがある環境 | Beanstalkdデーモン |
なぜ最初は「database」ドライバが最もおすすめなのか?
- 追加ミドルウェアのインストールが一切不要:RedisやSQSの契約・設定をすることなく、すでに接続しているMySQLやPostgreSQLのデータベーステーブルだけで即座に稼働します。
- データの可視化が極めて容易:データベース管理ツール(phpMyAdmin, DBeaver, TablePlus等)で
jobsやfailed_jobsテーブルを開くだけで、どんなジョブが待機中・失敗しているかが一目でわかります。 - データベーストランザクションとの親和性:
afterCommit()機能など、DBコミット成功時のみジョブを投入する制御が確実に行えます。
—
3. 【Step 1】databaseキュードライバの導入と初期設定
それでは、実際にLaravelプロジェクトで database ドライバを使ってキューを構築する手順を解説します。
手順①:環境変数(.env)の変更
プロジェクトルートの .env ファイルを開き、QUEUE_CONNECTION(旧バージョンでは QUEUE_DRIVER)の値を sync から database に変更します。
# 変更前(デフォルトの同期実行)
# QUEUE_CONNECTION=sync
# 変更後(データベースキューを使用)
QUEUE_CONNECTION=database
手順②:キュー用テーブル&失敗ジョブテーブルのマイグレーション
ジョブを保存する jobs テーブル、失敗したジョブを記録する failed_jobs テーブル、およびジョブバッチ用の job_batches テーブルを作成します。
# Laravel 11 / 12 の場合(デフォルトでマイグレーションファイルが用意されているか、以下で作成)
php artisan make:queue-table
php artisan make:queue-failed-table
php artisan make:queue-batches-table
# マイグレーションを実行してテーブルを作成
php artisan migrate
Laravel 10以前では以下のコマンドを使用します。
php artisan queue:tablephp artisan queue:failed-tablephp artisan queue:batches-tablephp artisan migrate
作成される主要テーブルの構造
マイグレーションを実行すると、データベースに以下のテーブルが作成されます。
jobsテーブル:実行待ちのジョブ、実行中のジョブ、遅延待機中のジョブが格納されます。ワーカーがジョブを取得して処理が成功すると、レコードは自動的に削除されます。failed_jobsテーブル:リトライ上限を超えて完全に失敗したジョブの例外スタックトレースや投入パラメータが記録されます。job_batchesテーブル:複数のジョブをグループ化して一括管理・進捗追跡するためのテーブルです。
—
4. 【Step 2】Jobクラスの作成と構造の理解
バックグラウンドで実行したい処理の単位を 「Job(ジョブ)クラス」 として定義します。
手順①:ArtisanコマンドでJobクラスを生成
以下のコマンドを実行すると、app/Jobs/ ディレクトリ配下に新しいJobクラスが生成されます。
php artisan make:job SendWelcomeEmailJob
手順②:Jobクラスの基本構造と構成要素
生成された app/Jobs/SendWelcomeEmailJob.php を開くと、以下のような構造になっています。
<?php
namespace App\Jobs;
use App\Models\User;
use App\Mail\WelcomeMail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
class SendWelcomeEmailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* 最大試行回数
*/
public int $tries = 3;
/**
* 再試行までの待機秒数(バックオフ)
*/
public int $backoff = 30;
/**
* タイムアウト秒数
*/
public int $timeout = 60;
/**
* ジョブインスタンスの生成(必要なデータを受け取る)
*/
public function __construct(
public User $user
) {
// PHP 8のコンストラクタプロパティプロモーション
}
/**
* ジョブの実行処理(バックグラウンドでワーカーが呼び出す)
*/
public function handle(): void
{
Log::info("ウェルカムメール送信ジョブを開始: ユーザーID={$this->user->id}");
// メール送信(Mailableを実行)
Mail::to($this->user->email)->send(new WelcomeMail($this->user));
Log::info("ウェルカムメール送信ジョブが完了: ユーザーID={$this->user->id}");
}
/**
* ジョブが完全に失敗した際の処理
*/
public function failed(\Throwable $exception): void
{
Log::error("ウェルカムメール送信が最終失敗: ユーザーID={$this->user->id}, エラー={$exception->getMessage()}");
}
}
implements ShouldQueue を削除しないでください!クラス宣言にある
implements ShouldQueue は、「このJobをキューに投入して非同期実行せよ」というLaravelへの指示マーカーです。これを消してしまうと、dispatch() を呼び出してもその場で同期実行(画面が待たされる)されてしまいます。
Jobクラスに含まれる4大トレイトの役割
| トレイト名 | 役割と提供メソッド |
|---|---|
Dispatchable |
SendWelcomeEmailJob::dispatch($user) のように静的メソッドから手軽にジョブをキュー投入できるようにする。 |
InteractsWithQueue |
キューの内部状態を操作するメソッド($this->release() で一時保留、$this->delete() で破棄、$this->attempts() で試行回数取得)を提供する。 |
Queueable |
遅延実行(delay())や接続先キュー名(onQueue())を指定するためのチェーンメソッドを提供する。 |
SerializesModels 🌟 |
Eloquentモデルを安全にシリアライズ(IDのみをDBに保存)し、ワーカー実行時に最新のモデルデータをDBから自動再取得する。 |
—
5. 【Step 3】Jobのディスパッチ(キュー投入)パターン集
コントローラやサービス層からJobをキューに投入する(ディスパッチする)ための多彩な方法をマスターしましょう。
① 基本のディスパッチ
use App\Jobs\SendWelcomeEmailJob;
// 最も標準的な投入方法
SendWelcomeEmailJob::dispatch($user);
② 遅延実行(ディレイ指定)
「登録の10分後にフォローメールを送る」「決済の1時間後にリマインドする」といった時限処理は delay() メソッドを使います。
// 10分後に実行
SendWelcomeEmailJob::dispatch($user)->delay(now()->addMinutes(10));
// 明日の朝9時に実行
SendWelcomeEmailJob::dispatch($user)->delay(now()->tomorrow()->setHour(9));
③ 特定のキュー名や接続先の指定
メール送信や重いバッチ処理など、ジョブの種類ごとにキューを分離したい場合は onQueue() を指定します。
// 'emails' という名前の専用キューに投入
SendWelcomeEmailJob::dispatch($user)->onQueue('emails');
// 別の接続設定(例: redis)に投入
SendWelcomeEmailJob::dispatch($user)->onConnection('redis');
④ レスポンス返却後の非同期実行(dispatchAfterResponse)
ワーカーを常駐させずに、Webサーバー(PHP-FPM/FastCGI)がお客さんにHTML/JSONレスポンスを返した直後の「余白時間」に処理を実行させたい場合に便利です。
// HTTPレスポンスをブラウザに返した直後にバックグラウンド実行
SendWelcomeEmailJob::dispatchAfterResponse($user);
⑤ トランザクション完了後にディスパッチ(afterCommit)
データベーストランザクション内でジョブを投入する際、「トランザクションがロールバックされたのにメールだけ送信されてしまう」「コミット前にワーカーがジョブを取得してしまい、DBレコードが見つからずエラーになる」という事故を防ぐための鉄則テクニックです。
use Illuminate\Support\Facades\DB;
use App\Jobs\SendWelcomeEmailJob;
DB::transaction(function () use ($request) {
$user = User::create([...]);
// DBコミットが成功した後にのみキューへ投入する
SendWelcomeEmailJob::dispatch($user)->afterCommit();
});
Jobクラス内に
public bool $afterCommit = true; プロパティを宣言しておくと、明示的に afterCommit() を呼ばなくても自動的にトランザクション完了を待つようになります。
⑥ 複数ジョブのチェーン(連鎖実行)とバッチ処理
「ジョブAが完了したらジョブBを実行し、最後にジョブCを実行する」という一連のパイプラインは Bus::chain() で記述できます。
use Illuminate\Support\Facades\Bus;
use App\Jobs\ProcessCsvImportJob;
use App\Jobs\CalculateSummaryJob;
use App\Jobs\SendAdminReportJob;
// 直列に順次実行(途中で失敗すると後続は中断)
Bus::chain([
new ProcessCsvImportJob($filePath),
new CalculateSummaryJob(),
new SendAdminReportJob(),
])->dispatch();
—
6. 【Step 4】Queue Worker(ワーカー)の起動とローカル開発
ジョブをキューに投入したら、キューに溜まったジョブを取り出して実際に実行する Queue Worker(キューワーカー) を起動します。
ワーカーの起動コマンド
php artisan queue:work
コマンドを実行するとコンソールが待機状態になり、ジョブが投入されると以下のようにリアルタイムで実行ログが流れます。
INFO Processing jobs from the [default] queue.
2026-08-28 12:00:01 App\Jobs\SendWelcomeEmailJob ......... RUNNING
2026-08-28 12:00:02 App\Jobs\SendWelcomeEmailJob ........ 1.23s DONE
queue:work と queue:listen の違い【重要】
ローカル開発時によく初心者がハマるのが、「ソースコードを修正したのにワーカーの動作が変わらない」という現象です。
| コマンド | 動作の仕組み | コード修正の反映 | 推奨用途 |
|---|---|---|---|
php artisan queue:work |
起動時にアプリケーション全体をメモリにロードし、常駐してジョブを高速処理する。 | 自動反映されない(再起動または queue:restart が必要) |
本番環境(高速・省リソース) |
php artisan queue:listen |
ジョブを受信するたびに新しいPHPプロセスを起動して実行する。 | 常に最新コードが自動反映される | ローカル開発環境(再起動の手間不要) |
ローカル開発中は
php artisan queue:listen を動かしておくと、JobクラスやMailableのコードを書き換えてもワーカーを再起動することなく即座に変更が反映されて快適です!
よく使うワーカー起動オプション
# 特定のキューを指定の優先度で処理(emailsキューを最優先で消化)
php artisan queue:work --queue=emails,default
# ジョブの最大試行回数を指定(3回失敗したらfailed_jobsへ移動)
php artisan queue:work --tries=3
# ジョブの最大実行秒数(60秒を超えたら強制終了)
php artisan queue:work --timeout=60
# メモリ制限(128MBを超えたら安全にプロセス再起動)
php artisan queue:work --memory=128
# スリープ秒数(キューが空のときの待機間隔)
php artisan queue:work --sleep=3
—
7. 【Step 5】本番環境でのワーカー常駐化(Supervisor設定)
ローカル環境ではターミナルで php artisan queue:work を手動実行できますが、本番サーバーではターミナルを閉じても常時稼働し続け、サーバー再起動時やクラッシュ時にも自動復旧する仕組みが必要です。
Linux環境における標準的なプロセスマネージャーである Supervisor(スーパーバイザー) の設定手順を解説します。
手順①:Supervisorのインストール
# Ubuntu / Debian の場合
sudo apt-get update
sudo apt-get install supervisor
# CentOS / RHEL / AlmaLinux の場合
sudo yum install epel-release
sudo yum install supervisor
sudo systemctl enable supervisord
sudo systemctl start supervisord
手順②:Supervisor設定ファイルの作成
/etc/supervisor/conf.d/laravel-worker.conf を作成し、以下の設定を記述します。
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/your-app/artisan queue:work database --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/your-app/storage/logs/worker.log
stopwaitsecs=3600
| 設定項目 | 説明・推奨値 |
|---|---|
numprocs=4 |
同時に起動するワーカープロセス数。CPUコア数やジョブ量に応じて並列数を設定。 |
autorestart=true |
予期せぬエラーやメモリ制限でプロセスが終了した際、Supervisorが自動で再起動する。 |
--max-time=3600 |
1時間経過したプロセスを安全に再起動し、PHPのメモリリークを予防する。 |
user=www-data |
Webサーバーと同じ実行ユーザー(ファイル権限トラブルを防ぐ)。 |
手順③:Supervisor設定の反映とワーカー起動
# 設定ファイルを読み込み
sudo supervisorctl reread
# 変更を反映してプロセスを起動
sudo supervisorctl update
# ワーカーの稼働ステータスを確認
sudo supervisorctl status
デプロイ時の重要ルール(queue:restart)
queue:work は起動時にコードをメモリにキャッシュするため、Gitプル等で新しいコードをデプロイした後は、必ず以下のコマンドを実行してワーカーに新しいコードを読み込ませる必要があります。
# デプロイスクリプトに必ず含める
php artisan queue:restart
このコマンドを実行すると、全ワーカープロセスは「現在処理中のジョブが完了したタイミング」で安全に終了し、Supervisorが即座に最新コードで新しいプロセスを起動してくれます。
—
8. 【Step 6】失敗ジョブの監視とエラーハンドリング
ネットワーク切断や外部API障害などでジョブが失敗した場合のリカバリ運用を把握しておきましょう。
失敗ジョブ管理のArtisanコマンド一覧
| コマンド | 実行内容 |
|---|---|
php artisan queue:failed |
failed_jobs テーブルに記録されている失敗ジョブの一覧(ID, キュー名, 例外)を表示。 |
php artisan queue:retry {id} |
指定したIDの失敗ジョブを再度キューに投入して再試行する。 |
php artisan queue:retry all |
失敗しているすべてのジョブを一括で再試行する。 |
php artisan queue:forget {id} |
指定した失敗ジョブを failed_jobs テーブルから削除する。 |
php artisan queue:flush |
failed_jobs テーブルの全レコードを削除・クリーンアップする。 |
—
9. 【実践ハンズオン】会員登録メール非同期送信の一気通貫実装
ここまでの知識を総動員して、実務で最も頻出する「会員登録時のウェルカムメール非同期送信」を完成させましょう。
① コントローラの実装(RegisterController)
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Jobs\SendWelcomeEmailJob;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\RedirectResponse;
class RegisteredUserController extends Controller
{
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
$user = DB::transaction(function () use ($validated) {
$user = User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => Hash::make($validated['password']),
]);
// DBコミット完了後に安全にジョブをキュー投入
SendWelcomeEmailJob::dispatch($user)->afterCommit();
return $user;
});
// ユーザーには即座に登録完了画面を返却(体感レスポンス爆速!)
return redirect()->route('dashboard')
->with('status', '会員登録が完了しました。確認メールをお送りしましたのでご確認ください。');
}
}
② Mailableクラスの実装(WelcomeMail)
<?php
namespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class WelcomeMail extends Mailable
{
use Queueable, SerializesModels;
public function __construct(
public User $user
) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'ご登録ありがとうございます!会員登録完了のお知らせ',
);
}
public function content(): Content
{
return new Content(
view: 'emails.welcome',
);
}
}
Mailableクラスに
implements ShouldQueue を付与すると、Mail::to($user)->queue(new WelcomeMail($user)); と呼び出すだけでJobクラスを作らずに直接メールをキュー投入することもできます。ただし、メール送信の前後に独自のログ記録やDB更新を挟む場合は、上記のように明示的なJobクラスを作成する構成が実務上最も柔軟で保守性に優れます。
—
10. よくあるエラー・トラブルシューティングFAQ
| トラブル・現象 | 主な原因 | 解決策 |
|---|---|---|
dispatch() しても処理が実行されない |
キューワーカー(queue:work)が起動していない。 |
別ターミナルで php artisan queue:work または php artisan queue:listen を起動してください。 |
.env を変更したのに sync のまま動く |
Laravelの設定キャッシュが残っている。 | php artisan config:clear を実行してキャッシュをクリアしてください。 |
| ModelNotFoundException が発生する | DBコミット前にワーカーがジョブを取得してしまい、該当IDのレコードが未確定。 | dispatch($model)->afterCommit() を指定するか、Jobクラスに public $afterCommit = true; を設定してください。 |
| コードを修正したのにワーカーの挙動が変わらない | queue:work が古いコードをメモリキャッシュしている。 |
php artisan queue:restart を実行するか、開発環境では queue:listen を使用してください。 |
—
11. 関連記事・あわせて読みたいLaravel実践ガイド
Laravelのパフォーマンスチューニングやバックエンド設計をさらに極めるための厳選関連記事です。あわせてご覧ください。
- 📧 Laravelメール送信完全ガイド|Mailableの使い方とBladeテンプレート・Mailpit/Mailtrapでの検証手順を徹底解説
本記事で解説した非同期キューと組み合わせて使うMailableクラスの基礎からテンプレート作成までを詳しく解説しています。 - ☁️ Laravel×S3画像アップロード完全ガイド|Storageファサード設定・Flysystem導入から公開URL取得・IAM権限まで徹底解説
重いファイル処理やS3アップロードをキューで非同期化する際のストレージ操作の完全版です。 - 🔒 Laravel トランザクションの使い方完全ガイド|DB::transactionの自動コミット・手動ロールバック・デッドロック再試行
キュー投入時の必須テクニックであるafterCommit()とデータベース整合性の担保方法を網羅しています。 - ⚡ LaravelのN+1問題を完全解決!with・loadによるEager Loadingと検知・防止テクニック
データベースクエリの最適化とWebレスポンス高速化の必須知識です。 - 🔄 Laravel Eloquentリレーション全種類まとめ|hasMany・belongsToの違いと正しい定義方法を徹底解説
Jobクラス内で関連モデルを効率的に扱うためのEloquentリレーション完全ガイドです。 - ⚙️ Laravelスケジューラでタスク自動化: 効率的にジョブ管理を行う方法
定期バッチやクーロンタスクからJobをディスパッチする自動化手法を解説しています。
—
12. まとめ:キューと非同期処理で高パフォーマンスなWebアプリを作ろう
Laravelのキュー機能を導入することで、ユーザーを待たせることなく重い処理を安全に裏側で実行し、Webアプリケーションのレスポンスと耐障害性を劇的に向上させることができます。
.envでQUEUE_CONNECTION=databaseを設定したか?php artisan make:queue-tableとmigrateでテーブルを作成したか?- Jobクラスに
implements ShouldQueueを付与したか? - DBトランザクション内のディスパッチには
afterCommit()を指定したか? - ローカル開発では
queue:listen、本番ではSupervisorを導入したか? - 本番デプロイ時に
php artisan queue:restartを実行しているか?
まずは手軽な database ドライバから始めて、快適でスケーラブルなLaravelアプリケーションを構築していきましょう!

コメント