深入了解laravel消费队列的两种工作模式
Posted coder_up
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入了解laravel消费队列的两种工作模式相关的知识,希望对你有一定的参考价值。
由来
一直在用laravel的Queue, 并且最近使用中也遇到一些问题,急迫的想搞清楚Laravel中的Queue到底是如何跑起来的 大家都知道Queue的运行有两种模式,一种是Wok, 一种是Listen, 在看过的博客中讲到的都不是很深入,大部分都是重复的Copy, 没有特别详细的讲解,知其然,而不知所以然,对于喜欢为Why
的Coder来说很痛苦,于是就有了这篇文章,希望对您能有帮助
辅助工具
- xhprof, xhgui
- socketLog
宏观上分模块理解Queue消费的工作过程
下面我将一个完整的消费过程分为以下步骤理解,以及详细的陪图说明
- 命令行初始化模块
- 消费队列命令运行模块
- 任务的存储与操作
- 唤起执行任务的模块
- 具体任务执行模块
下面是一张UML图像,我把上面的5个模块中用到的重要的类都画了下来
在线浏览地址
点击链接
下面是一张类函数调用堆栈图,时序图太长画出来也不大好看
微观理解Listener VS Worker的区别
几种运行模式
queue:work || queue:work --once
默认只执行一次队列请求, 当请求执行完成后就终止;queue:listen
监听队列请求, 只要运行着, 就能一直接受请求, 除非手动终止;queue:work --daemon
同 listen 一样, 只要运行着, 就能一直接受请求, 不一样的地方是在这个运行模式下, 当新的请求到来的时候, 不重新加载整个框架, 而是直接 fire 动作, 当更新代码的时候, 需要停止, 然后重新启动, 这样修改的代码才能起作用
Laravel5.3之前和之后对Worker的timeout有改动,>=5.3的version Work模式也支持了超时检测
相同点
- 最终都是执行的work
<5.3
->queue:work %s --queue=%s --delay=%s --memory=%s --sleep=%s --tries=%s
>=5.3
->queue:work %s --once --queue=%s --delay=%s --memory=%s --sleep=%s --tries=%s
下面的图片中可以看到, work只是执行了一次WorkCommand,然后循环处理每个任务, listen是用ListenCommand作为一个入口或者叫包装器,实际里面真正执行的还是work once
work
listen
不同点
- Listen 方式使用的是Process实例去循环的执行Work Once, 所以你修改的Job代码会被从新加载,因为Listen的消费是单独开启独立的进程去消费的,当然浪费性能有进程开销
- Work 方式是while(true), 在当前的进程中去处理任务, 修改的代码不会生效
- Work的超时机制,在Laravel<=5.2前Work是不支持超时参数的,在Laravel>=5.3起,Work的daemon模式也开始支持超时机制了,这种机制使用的
时钟 pcntl_alarm
机制,时间到达后出发信号执行kill进程的操作,这种模式开启的要求是version_compare(php_VERSION, '7.1.0') >= 0 && extension_loaded('pcntl')
- Listen的超时机制, 只要进程运行着就会自动检测
function wait()
...
do
$this->checkTimeout();
...
while ($running);
...
使用流程图来描述一个任务的执行过程
再来说下redis中的任务是在何时被删除的,如何删除的
当一个任务被lpop
弹出之后,同时会将该认为添加到这个名字的队列中[当前队列名+:reserved
],如上图,
在执行过程中如果任务在指定时间没有错误的正确执行完毕,那么这个任务会自动调用deleteReserved
销毁, 假如执行有异常或者超时了,那么要判断任务的最大执行次数是否达到,没达到则再次release
到队列中同时尝试次数加一,如果达到最大执行次数则执行执行失败,并将信息记录到数据库中.当然pop出消息前,还有一个步骤就是合并reserved,delayed的任务到队列中
以上是关于深入了解laravel消费队列的两种工作模式的主要内容,如果未能解决你的问题,请参考以下文章