タイトルのとおりです。
Laravelのキューは非常に良くできていて、ワーカープロセスを別途立ち上げると常時ワーカーがキューイングされたジョブを調べ、実行してくれる仕組みを持っています。
しかもLinuxであればデーモン化して、常駐させるための仕組みもデフォルトで持っているという親切設計です。
ただ、一般的なレンタルサーバですとSSHでアクセスできたとしても常駐プロセスを立ち上げておくのは難しいですよね。
今どきならCronぐらいは使えるサーバが多いと思うので、多少ジョブの実行が遅れてもいいので、Cronでキューイングされたジョブを処理できれば・・!と思いました。
Laravelだとタスクスケジューリングの仕組みもあって、そちらでタスクを実行できれば良いんですが、メール送信などを遅延させるのはキューであってタスクじゃないんですね(laravelの仕様上)。
まぁ妥当というか当然な設計ですし、そこを組み替えるようなカスタムは気持ち悪いのでやりたくありません。
そんなこんなでなにかいい方法はないものかと悩みつつ、いろいろ調べたところ最終的に参考になったのが以下の感じ。というかほぼ抄訳です。
Queue solution for shared hosting
Using laravel Queues on shared hosting: A simple guide
要するに
- Cronで動くLaravelのタスクスケジューラを使い、
- タスクの中でキューのワーカープロセスを実行
です。
具体的にはconsole/Kernel.phpにて以下のようにタスクを設定します。
console/Kernel.php
$schedule->command('queue:restart')->everyTenMinutes(); $schedule->command('queue:work --tries=3')->everyMinute()->withoutOverlapping();
また、レンタルサーバのCron設定にて
* * * * * php /path-to-project/artisan schedule:run >> /dev/null 2>&1
って感じに設定しておくと完了です。
ワーカープロセスがたくさん残りそうだけど、withoutOverlappingがあるから大丈夫なのかな。あとで実装読もう。
あとはサーバ業者が長生きしたプロセスを殺すのを期待?(設定変更反映の為restart入れてるけど)
追記
ジョブがこけるとfaild_jobsテーブルに退避されるのですが(設定していれば)、タスクスケジューラでのジョブキューワーカの起動がしなくなる場合があります。
この場合、フレームワークのキャッシュクリアを行うと、再度ワーカプロセスが立ち上がる様になる模様。
コメント