Laravel 的 queue worker 與 Horizon 需要透過 artisan queue:work
在背景執行,若可以的話,再使用 systemd 或 supervisor 來監控運作狀態。
不過 systemd 和 supervisor 都需要 root 權限來操作,說起來蠻麻煩的,所以寫了一小段 shell script 來啟動與停止,沒辦法在 worker 中斷時 restart,但可以做 graceful start & shutdown。
啟動 queue worker:
./artisan queue:work \ --no-interaction --no-ansi >> storage/logs/queue.log 2>&1 & # 透過 $? 來檢查指令執行是否成功 if [ $? -ne 0 ]; then echo "FAILED !" else echo "OK" fi
停止所有的 queue worker:
# queue:restart 會送訊號給所有的 worker 來 graceful shutdown ./artisan queue:restart --quiet --no-ansi # 檢查是否所有的 proccess 都停止 while [ 1 ]; do QUERY="$(ps -ef | grep queue:work | grep -v grep)" if [ -z "${QUERY}" ]; then break else sleep 1 fi done echo "OK"
Laravel Horizon 的操作相對簡單一些。
啟動 Horizon:
./artisan horizon \ --quiet --no-interaction --no-ansi >> storage/logs/horizon.log 2>&1 & if [ $? -ne 0 ]; then echo "FAILED !" else echo "OK" fi
停止 Horizon:
artisan horizon:terminate --quiet --no-interaction --no-ansi # 檢查 proccess 是否終止 while [ 1 ]; do QUERY="$(ps -ef | grep horizon | grep -v grep)" if [ -z "${QUERY}" ]; then echo "OK" else sleep 1 fi done
queue:restart 字面上看起來是重新啟動,好像不算是停止?
文字上是「重新啟動」,但自己測試時,僅會停止現有的 worker 但不會再次 start
剛剛翻了一下 code
artisan queue:restart
的 source file 在Illuminate\Queue\Console\RestartCommand.php
,執行以後,會在 cache 寫一個 timestamp。而
Illuminate\Queue\Worker.php
的getTimestampOfLastQueueRestart
中會去檢查 cache data,但是在哪裡會中斷、重新執行我還沒追到,這個檔案太肥了 Orz看起來是在
Worker.php
的stopIfNecessary()
中,會停止,但是似乎不會啟動另外 worker 啟動時,會去檢查 cache 取得 queue 停止的時間,應該是透過這個機制取得最後執行的 job(s)
唔 …. 好像應該加個
nohup
…