讓 queue work 開始執行任務的指令有兩個:work 和 listen
$ php artisan queue:work
$ php artisan queue:listen
Remember, queue workers, are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers. In addition, remember that any static state created or modified by your application will not be automatically reset between jobs.
Alternatively, you may run the queue:listen command. When using the queue:listen command, you don't have to manually restart the worker when you want to reload your updated code or reset the application state; however, this command is significantly less efficient than the queue:work command.
其實官方文件解釋得滿清楚的了,簡單來說,listen 是 worker 每次執行完一個任務就被 kill 掉,重啟一個新的 worker process。所以如果還在開發,code 有更改,listen 會表現出來;如果是用 work 的話,必須手動去重啟。
實際去觀察Illuminate\Queue\Worker
,在__construct
裡埋 code:
public function __construct()
{
// ...
printf("%s: created a worker\n", now()->format('Y-m-d H:i:s'));
}
然後分別執行 queue:listen
和 queue:work
去觀察,可以發現 listen
會一直跳~
$ php artisan queue:listen
2021-09-08 18:38:07: created a worker
2021-09-08 18:38:07: created a worker
2021-09-08 18:38:10: created a worker
2021-09-08 18:38:13: created a worker
2021-09-08 18:38:16: created a worker
2021-09-08 18:38:19: created a worker
2021-09-08 18:38:23: created a worker
2021-09-08 18:38:26: created a worker
...
queue:work 有效, queue:listen 無效
job 的 timeout 只有在 queue:work
才有效,因為 timeout 是時間超過會 kill worker process;而queue:listen
是每次都會重建新的 worker process,所以根本不需要根據 timeout 去停止 worker。
進到 Illuminate\Queue\Worker
就可以看到,要先進到 daemon()
,才會去跑 registerTimeoutHandler
,也就是實際判斷是否 timeout 的地方。
如果在 daemon()
和 __construct
裡分別埋 dump()
去執行 queue worker 觀察,可以發現執行 artisan queue:listen
的話, daemon
的 dump
沒有觸發,但 construct
裡的一直印出;對比,如果執行 artisan queue:work
,construct
只會跑一次,且會進到 daemon()
,daemon()
裡有一個 while(true)
所以會一直loop。