どうもこんにちは
メール送信処理を非同期的に送信したかったので、
LaravelのQueueと、プロセス監視にSupervisorを使いました。
ま、先人たちがすでにさんざんやっておられる、アレです。
それぞれにわかりやすく執筆されている方はいらっしゃいますが
両方をまとめて1記事にされているものが少なかったので、備忘録をかねて。
Laravelのバージョンは5.8、EC2にSupervisorをインストールして動作させてみます。
では、参りましょう。
Supervisor本家サイトはこちら ⇒ Supervisor: A Process Control System — Supervisor 4.0.3 documentation
目次
Laravelのあれこれ
.envファイル
今回はデータベースドライバを使いました。
EC2だったらSQSを使えばいいんじゃねーのっていう声は聞こえません。
.envファイルを編集します。
1 |
QUEUE_CONNECTION=database |
config/queue.phpについては、特に触りませんでした。
Migrate
キュー管理用テーブルのmigrateです。
公式がきちんと用意してくれています。ありがたや。
キュー処理が失敗した時用のテーブルも一緒に作ります。
1 2 3 |
php artisan queue:table php artisan queue:failed-table php artisan migrate |
メール送信処理
メール送信処理をすこーし変えます。
今回はメールファサードで送っているので、Mail::sendをMail::queueに変えて回るだけです。
1 |
Mail::to(Auth::user())->send(new MyMailSender); |
が
1 |
Mail::to(Auth::user())->queue(new MyMailSender); |
にしました。
実際に動かすと、jobsテーブルにレコードが追加されます。
※キューワーカーを起動していないと、たまる一方なのは当たり前。
補足
今回はメール送信処理なので、
php artisan make:mail MyMailSender
で作ったメール送信クラスを使っています。
メール送信でない処理は
php artisan make:job MyJobProcessor
のようにJobクラスを作って、
1 |
MyJobProcessor::dispatch(); |
でキューに放り込むようです。
dispatchメソッドの引数はMyJocProcessorのコンストラクタの引数だそうです。へー
Supervisor
SupervisorをEC2にインストールしてみます。
環境
念のため、ですが
こんな環境です。
1 2 3 4 5 6 7 8 |
$ python --version Python 2.7.16 $ cat /etc/system-release Amazon Linux AMI release 2018.03 $ arch x86_64 |
インストール
公式ドキュメントによると、
$ pip install supervisor
らしいのですが、
$ easy_install supervisor
で入れてしまいました。
ま、いいか。
設定ファイル作成と編集 その1
設定ファイルのひな形があるので、それをもとに/etc/supervisord.conf を作ります。
# echo_supervisord_conf > /etc/supervisord.conf
#$ sudo ~~~~
だとなぜかpermission deniedになったので、
rootにスイッチしてからやりました。
あとは、ファイルを編集します。
いろいろ端折りますが、編集したのはこれくらいです。
1 2 3 4 5 6 7 8 9 10 11 |
: (中略) : [supervisord] ;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log logfile=/var/log/supervisord.log : (中略) : [include] files = /etc/supervisord/conf.d/*.conf |
[include]の前のコメントを外すのをお忘れなく。(それで数時間はまりました。。。)
設定ファイル作成と編集 その2
laravelのキューワーカ用設定ファイルを作ります。
/etc/supervisord/conf.d/laravel-worker.confを下のように作りました。
1 2 3 4 5 6 7 8 9 |
[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/html/musicbase/artisan queue:work --tries=5 --timeout=60 --sleep=3 autostart=true autorestart=true user=ec2-user numprocs=3 redirect_stderr=true stdout_logfile=/var/log/laravel-worker.log |
commandのところが、laravelのキューコマンドです。
オプションは、公式ドキュメントを参考に、適宜与えました。
サービス登録
せっかくなので、サービスに登録しておきます。
スクリプトがこちらで公開されていたので
ありがたく使わせていただきました。
/etc/init.d/supervisordファイルに、スクリプトを記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
#!/bin/bash # # supervisord Startup script for the Supervisor process control system # # Author: Mike McGrath <mmcgrath@redhat.com> (based off yumupdatesd) # Jason Koppe <jkoppe@indeed.com> adjusted to read sysconfig, # use supervisord tools to start/stop, conditionally wait # for child processes to shutdown, and startup later # Erwan Queffelec <erwan.queffelec@gmail.com> # make script LSB-compliant # Greg Smethells <gsmethells@mgmail.com> #. Allow supervisorctl to be overridden # # chkconfig: 345 83 04 # description: Supervisor is a client/server system that allows \ # its users to monitor and control a number of processes on \ # UNIX-like operating systems. # processname: supervisord # config: /etc/supervisord.conf # config: /etc/sysconfig/supervisord # pidfile: /var/run/supervisord.pid # ### BEGIN INIT INFO # Provides: supervisord # Required-Start: $all # Required-Stop: $all # Short-Description: start and stop Supervisor process control system # Description: Supervisor is a client/server system that allows # its users to monitor and control a number of processes on # UNIX-like operating systems. ### END INIT INFO # Source function library . /etc/rc.d/init.d/functions # Source system settings if [ -f /etc/sysconfig/supervisord ]; then . /etc/sysconfig/supervisord fi # Path to the supervisorctl script, server binary, # and short-form for messages. supervisorctl=${SUPERVISORCTL-/usr/bin/supervisorctl} supervisord=${SUPERVISORD-/usr/bin/supervisord} prog=supervisord pidfile=${PIDFILE-/var/run/supervisord.pid} lockfile=${LOCKFILE-/var/lock/subsys/supervisord} sockfile=${SOCKFILE-/var/run/supervisord.sock} STOP_TIMEOUT=${STOP_TIMEOUT-60} OPTIONS="${OPTIONS--c /etc/supervisord.conf}" RETVAL=0 start() { echo -n $"Starting $prog: " daemon --pidfile=${pidfile} $supervisord $OPTIONS RETVAL=$? echo if [ $RETVAL -eq 0 ]; then touch ${lockfile} $supervisorctl $OPTIONS status fi return $RETVAL } stop() { echo -n $"Stopping $prog: " killproc -p ${pidfile} -d ${STOP_TIMEOUT} $supervisord RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -rf ${lockfile} ${pidfile} ${sockfile} } reload() { echo -n $"Reloading $prog: " LSB=1 killproc -p $pidfile $supervisord -HUP RETVAL=$? echo if [ $RETVAL -eq 7 ]; then failure $"$prog reload" else $supervisorctl $OPTIONS status fi } restart() { stop start } case "$1" in start) start ;; stop) stop ;; status) status -p ${pidfile} $supervisord RETVAL=$? [ $RETVAL -eq 0 ] && $supervisorctl $OPTIONS status ;; restart) restart ;; condrestart|try-restart) if status -p ${pidfile} $supervisord >&/dev/null; then stop start fi ;; force-reload|reload) reload ;; *) echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload}" RETVAL=2 esac exit $RETVAL |
パーミッションの変更をお忘れなく。
# chmod 755 /etc/init.d/supervisord
あとは、サービス登録ですね。
# chkconfig supervisord on
起動とか
ここまでしておくと、serviceコマンドから起動できます。
起動
# service supervisord start
終了
# service supervisord stop
再起動
# service supervisord restart
起動すると、
1 2 3 4 5 |
# service supervisord start Starting supervisord: [ OK ] laravel-worker:laravel-worker_00 STARTING laravel-worker:laravel-worker_01 STARTING laravel-worker:laravel-worker_02 STARTING |
こんな感じで、キューワーカが起動します。
最後に
Supervisorから出力されるログをローテーションする設定は入れとかないと、ですね。
キューの仕掛けまで用意しているとは、モダンなフレームワーク、恐るべし。
r.tanakaがお届けしました。