Laravel Queue Job:深入理解 timeout 的运作

work 和 listen 的差别

让 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:listenqueue: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
...

深入理解 timeout 的运作

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 的话, daemondump 没有触发,但 construct 里的一直印出;对比,如果执行 artisan queue:workconstruct 只会跑一次,且会进到 daemon()daemon()里有一个 while(true) 所以会一直loop。

Reference


<<:  [Day11] 在 GCP 上建立 VM 与布署 API 程序

>>:  Day 11 - Custom HTML5 Video Player

Python Flask API 初探

昨天架设完Python环境後, 今天要开始架设Python API的专案, 而我们今天使用的是Fla...

中阶魔法 - 闭包 Closure (二)

前情提要 艾草:「昨天教你原理,今天我们实际来实作这个术式吧!」 「好~~」 艾草:「来!发动前要念...

Day 10 Dart语言-混合及泛型

混合mixins 介绍:mixin是一种可以把自己的方法提供给别的类别使用,却不需要成为其他类别的父...

第12章:SSH远端连线设定与原理介绍(三)

前言 在前一章节中,使用了ssh-keygen来演示如何使用金钥交换的方式进行验证,在本章节中,将会...

Day10-为了让表单资料不要太过自大,给予其正确的绝望-Validation(III)

标题参考来源 大家好~ 今天来认识如何自定义错误讯息且不用另外建立 FormRequest clas...