0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「動くはずのジョブが動かない!?」メンテナンスモードの罠 - Laravel

Posted at

Laravelのキューとワーカーは非同期処理を実装する上でとても便利ですが、メンテナンスモード中の挙動には注意が必要です。結論、以下のポイントを押さえておくと良いです。

結論

  • メンテナンスモード中は、キュー上のジョブは処理されない

  • Laravel では、バージョン10 以降、公式ドキュメントに「メンテナンスモード中はキューが実行されない」と明記されている

  • どうしてもメンテナンス中にジョブを処理する場合は --force オプションを使用する

  • 実運用ではジョブの依存関係やサーバ負荷を考慮して運用することが重要

1. Laravel のキューとワーカーの基本

Laravelのキューは、jobsテーブルやRedis、SQSなどのドライバーを通じて、非同期にジョブを処理する仕組みです。ジョブをキューに投入することで、メール送信や画像処理、外部API呼び出しなど、時間のかかる処理をバックグラウンドで実行できることがメリットです。

キューやジョブについて初めて聞いたという方は以下のようにレストランの注文システムをイメージすると整理しやすいと思います。

  • ジョブ(Job) = 「注文票」

    • 具体的に「何をやるべきか」が書かれたタスク。

    • 例:ハンバーグを焼く、サラダを作る、ドリンクを出す。

  • キュー(Queue) = 「注文待ちのホワイトボード(待機列)」

    • 注文票が並んで置かれていて、順番待ちをしている場所。

    • 「これを処理してくださいね」とジョブが順番に積み上がっていく。

  • ワーカー(Worker) = 「料理人」

    • ホワイトボードを見に行き、「よし、次はハンバーグだな」と取り出して実行する人。

    • 料理が終わったら次の注文票を取りに行く。

ジョブ(注文票)をキュー(ホワイトボード)にセットして、ワーカー(料理人)はキューを見にいきながらジョブ(注文票)を処理していくという流れです。
ワーカー(料理人)が複数いれば同時並行で処理することも可能で、効率的にジョブを実行できます。

1.1 ジョブの作成例

ターミナル
php artisan make:job SendWelcomeEmail
class SendWelcomeEmail implements ShouldQueue { 
	use Dispatchable, Queueable, SerializesModels; 

	public function handle(): void { 
		Mail::to($this->user)->send(new WelcomeMail($this->user));
	}
}

1.2 キューへの投入

SendWelcomeEmail::dispatch($user);

2. ワーカーの実行方法とオプション

ワーカーはキューを監視し、ジョブを順次処理するプロセスです。

ターミナル
php artisan queue:work

代表的なオプション

  • --queue=default : 特定のキューのみ処理

  • --tries=3 : 失敗したジョブを再試行

  • --timeout=90 : 1ジョブの最大実行時間

  • --force : メンテナンスモード中でも実行

ワーカーを常時稼働させる場合は、Supervisorなどのプロセスマネージャーで管理するのが一般的です。

3. メンテナンスモード中のキュー挙動

Laravel では、バージョン10 以降、公式ドキュメントに 「メンテナンスモード中はキューが実行されない」 と明記されています。
※それ以前のバージョンでも制限がかかっていた可能性はありますが、公式ドキュメントのキューの仕様には記載が見つかりませんでした
メンテナンスモード中は、通常のWebアクセスだけでなくワーカーも停止するため、投入済みのジョブは処理されません。モード解除後にキューは再び処理を開始します。

ターミナル
php artisan down # メンテナンスモード開始 

php artisan up # メンテナンスモード解除

4. メンテナンスモード中でもジョブを動かす方法

今回の主題ですが、メンテナンス中にどうしてもジョブを実行したい場合は、--force オプションを使用することで実行が可能になります。

ターミナル
php artisan queue:work --force

これにより、メンテナンスモードを無視してワーカーがジョブを処理します。ただし、外部API呼び出しやデータベース操作が安全に行えるかはケースに応じて十分に確認する必要があります。

5. 実運用での注意点

5.1 Supervisorでのワーカー管理

長時間稼働するワーカーは、Supervisorで管理するのが一般的です。

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/worker.log
  • autorestart でワーカーの異常停止時も自動復旧
  • numprocs で並列処理のワーカー数を管理

5.2 ジョブ依存関係とキュー分離

  • メンテナンスモード中に動かすと不整合になるジョブは、専用のキューに分離しておく
  • メンテナンス中でも実行可能なジョブとそうでないジョブを明確に分けることで、リスク管理が容易

5.3 タイムアウト・再試行設定

  • 長時間ジョブや外部依存ジョブは、--timeout--tries を適切に設定
  • メンテナンスモード解除直後にジョブが大量処理される場合は、サーバ負荷に注意

5.4 --force の安全活用

  • 小規模ジョブやDB更新の影響が少ないジョブに限定する
  • 外部APIやメール送信などの重要処理は、通常通りメンテナンス解除後に処理する

6. まとめ

Laravel では、メンテナンスモード中はワーカーも停止し、ジョブは処理されないことが公式に明記されています。ただし、--force オプションを使えばメンテナンスモード中でもジョブを強制的に処理は可能です。
メンテナンスモード中にジョブを無理に動かす場合は、データや外部サービスへの影響に十分注意が必要です。

採用情報

アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドエンジニアを募集しています!
少しでも興味のある方は、カジュアル面談からでもお気軽にお話ししましょう!

お問い合わせはこちらから↓
https://official.assisteng.co.jp/contact/

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?