🎻
Symfony Messengerのmessage:consumeコマンドをcronで手軽に擬似常駐
小ネタです。
Symfony Messenger
symfony/messenger はメッセージキュー機構を導入するためのSymfonyコンポーネントです。
キューに溜められたメッセージ(ジョブ)は messenger:consume
コマンドを常駐させることで実際に処理されるようになります(messenger:consume
コマンドが起動されていない限りはキューに溜まるばかりで実際には処理されません)。
messenger:consume
コマンドを常駐させる方法は色々あり、例えばSymfonyの公式ドキュメントでは Supervisorなどを使う場合の設定方法が紹介されています が、Supervisorなどのミドルウェアを使うと、新しいコードをデプロイする度に常駐プロセスの再起動が必要でちょっと面倒です。
cronで擬似常駐
そこで、cronを使って擬似的に常駐させる方法を紹介します。
if [ `ps aux | grep messenger:consume | grep -v grep | wc -l` -eq 0 ]; then /path/to/php -d memory_limit=-1 -d date.timezone=Asia/Tokyo /path/to/project/bin/console messenger:consume --time-limit=60 >> /path/to/messenger.log 2>&1 ; fi
こんな感じのワンライナーをcronで * * * * *
とスケジュールして1分ごとに実行することで、
- 1分ごとに起動する
- 1分待って1つもメッセージがエンキューされてこなければ終了する(次のプロセスが起動されるので)
- 1分以内に1つでもメッセージがエンキューされてきたら、そこからは(1分を超えても)処理が終わるまでは終了しない
- 処理中のメッセージがあれば新たに起動はしない
ということが実現できます(ただし、メッセージの処理が完了してから次の1分の区切りまでには空白の時間が発生し得ます)。
なお、グローバルの php.ini
で date.timezone
を設定していない場合は -d date.timezone=Asia/Tokyo
を付けるのを忘れないようにしましょう。WebとCLIでタイムゾーンがズレていると、エンキューだけされて処理が一向に始まらないという現象になって地味にハマります。
おわり
もっとスマートな方法があったらぜひ教えてください🤲
Discussion