laravel框架中queue:listen 和 queue:work --daemon 的区别
2017-05-15 15:35
591 查看
三种情况:
queue:work默认只执行一次队列请求,
当请求执行完成后就终止;
queue:listen监听队列请求,
只要运行着, 就能一直接受请求, 除非手动终止;
queue:work --daemon同
listen一样,
只要运行着, 就能一直接受请求, 不一样的地方是在这个运行模式下, 当新的请求到来的时候,
不重新加载整个框架,
而是直接 fire 动作.
能看出来,
queue:work --daemon是最高级的, 一般推荐使用这个来处理队列监听.
注意: 使用
queue:work --daemon, 当更新代码的时候, 需要停止, 然后重新启动, 这样才能把修改的代码应用上.
至于存在的必要
首先, --daemon是在
Laravel 4.2 以后才加入的.
其次, 从上面的分析来看,
queue:listen和
queue:work --daemon还是有区别的.
在laravel中可以选择多种队列服务,常见的有redis和beanstalk,由于redis是单纯的db,数据完全透明所以这里用redis作为讲解对象会更加好理解。
laravel中队列的启动方式有
queue:listen和
queue:work,
其中
queue:work表示单独运行下一个job. 关于区别请看:queue:listen
和 queue:work --daemon 的区别。
queue:listen内部也是一次次的调用
queue:work实现的,现在我们来看
work命令。
在
IlluminateQueueConsoleWorkCommand中是不是看见了我们熟悉的
fire方法?对就是它。继续追,
调用
runWork方式查找job并且执行.这里有一个
daemon选项,
表示是否作为守护运行。直接将daemon认为false(因为daemon其实就是一个while(true) ):joy:。
看到
runWork其实是调用的
IlluminateQueueWorker::pop方法
public function pop($connectionName, $queue = null, $delay = 0, $sleep = 3, $maxTries = 0) { $connection = $this->manager->connection($connectionName); //这里就是你说的连接名称,实际就是选择一个合理的queue服务,只要你没有用某个队列服务的特有的方法,那么各个队列可以随时切换使用的. $job = $this->getNextJob($connection, $queue); //查找一个job对象 // If we're able to pull a job off of the stack, we will process it and // then immediately return back out. If there is no job on the queue // we will"sleep"the worker for the specified number of seconds. if ( ! is_null($job)) { //如果job存在则执行任务 return $this->process( $this->manager->getName($connectionName), $job, $maxTries, $delay ); } $this->sleep($sleep); return ['job' => null, 'failed' => false]; }
到了最终执行job的位置(删掉了空行和注释,因为我要来上蹩脚的中文注释了.(逃 ):
public function process($connection, Job $job, $maxTries = 0, $delay = 0) { if ($maxTries > 0 && $job->attempts() > $maxTries){ //看见了吗,运行的时候先查看了job的执行次数如果超过了最大次数,则直接进入logFailedJob过程,也就是将失败的job存储到指定的数据库中, 观察`IlluminateQueueJobsRedisJob`中的`attempts `方法和`release`方法。一个查看attempts次数,一个增加attempts次数(当然release还有其他操作).那么找找谁调用了release方法(看下面的trycatch,就是在出现异常之后并且job没有被删除的情况下会调用release)?如果没有抛出异常?那么attempts是不会变化的。 return $this->logFailedJob($connection, $job); } try{ $job->fire();// job的fire方法实际已经将我们指定的JobClass用Container::make并且执行了fire方法. if ($job->autoDelete()) $job->delete(); return ['job' => $job, 'failed' => false]; } catch (Exception $e){ if ( ! $job->isDeleted()) $job->release($delay); throw $e; } }
恩,差不多就是这么回事了。
相关文章推荐
- laravel queue:work & queue:listen
- softirq/tasklet/workqueue的区别
- softirq/tasklet/workqueue的区别
- softirq/tasklet/workqueue的区别
- tp框架和laravel框架的区别
- laravel框架的{{asset}}和{{url}}有什么区别
- softirq/tasklet/workqueue的区别
- softirq/tasklet/workqueue的区别
- softirq / tasklet / work queue 的区别
- TP框架和Laravel框架的区别
- Laravel框架中Blade模板引擎的一些标签的区别介绍
- softirq/tasklet/workqueue的区别
- softirq/tasklet/workqueue的区别
- PHP的Laravel框架中使用消息队列queue及异步队列的方法
- laravel框架与thinkPHP框架的区别
- softirq/tasklet/workqueue的区别
- PHP的Laravel框架中使用消息队列queue及异步队列的方法
- softirq/tasklet/workqueue的区别
- softirq/tasklet/workqueue的区别
- laravel框架自带缓存学习,和一些缓存的区别理解