时间:2021-07-01 10:21:17 帮助过:23人阅读
还有,Laravel5.2的queue:work并没有--timeout=60这个参数。。。。。
最后是队列执行完的处理逻辑。
如果队列执行成功会删除jobs的数据,这没什么问题。如果失败,包括超时、异常等,会根据设置的最大失败次数判断是否插入一条新数据,或者插入一条Failed数据到“failed_jobs”表。
出现错误时,handleJobException的异常处理调用DatabaseQueue.php的release方法,$job->release($delay),最终是pushToDatabase实现。
插入新数据时候,attempts是失败次数,reserved为0,available_at为当前时间戳加上超时配置时间,
这样整个队列处理就形成了完整的数据操作。
Laravel5.4对队列功能进行了很大的修改,手册中的提示
任务执行时间
在配置文件 config/queue.php
中,每个连接都定义了 retry_after
项。该配置项的目的是定义任务在执行以后多少秒后释放回队列。如果retry_after
设定的值为 90
, 任务在运行 90
秒后还未完成,那么将被释放回队列而不是删除掉。毫无疑问,你需要把 retry_after
的值设定为任务执行时间的最大可能值。
Laravel5.4去掉了queue的listen命令,work也增加了超时参数。Laravel5.5出来的时候应该必须直接升级上去。
附录:Laravel5.2测试的脚本,之前网上搜出来的都比较早,还是把job写成命令的方式,其实5.2以后job使用非常简单。
jobs下定义job任务,handle可以增加一些测试方案,比如我这种抛出异常,直接Failed的
class MyJob extends Job implements ShouldQueue { use InteractsWithQueue, SerializesModels; private $key; private $value; /** * Create a new job instance. * * @return void */ public function __construct($key, $value) { $this->key = $key; $this->value = $value; } /** * Execute the job. * * @return void */ public function handle() { for($i=0;$i<20;$i++){ echo "$i\n"; sleep(1); } echo "sss\t".$this->key."\t".date("Y-m-d H:i:s")."\n"; throw new \Exception("测试\n"); // Redis::hset(‘queue.test‘, $this->key, $this->value); } public function failed() { dump(‘failed‘); } }
控制器访问设置任务队列,key和value之前用了测试redis插入的,可以按自己的测试方案设置job参数。
for($i = 0; $i < 5; $i ++) { echo "$i"; $job = (new MyJob($i, $i))->delay(20); $this->dispatch($job); }
我的例子设置了5个队列,开启多个shell并发执行artisan测试吧。
本来想将redis队列代码读完,一起发出来的,最近事情太多,redis代码也没怎么看。
redis驱动可以参考 http://www.cnblogs.com/z1298703836/p/5346728.html 这篇文章对Laravel队列redis驱动逻辑介绍的很详细了,redis驱动使用的list和zset结构储存队列,执行过程会移除转存队列,没有数据库的“for update” 操作,所以应该不是存在队列阻塞的情况。
BUT队列任务过期时间设置和数据库驱动是一样的,所以同样
queue:listen的执行时间参数 --timeout=60,一定要设置小于队列任务过期时间expire参数!
终于写完了。。。
Laravel5.2队列驱动expire参数设置带来的重复执行问题 数据库驱动
标签:laravel php 队列