浅谈Laravel队列实现原理解决问题记录
Laravel  /  管理员 发布于 8年前   185
问题 公司项目使用Laravel的开发的两个项目在同一个测试服务器部署,公用同一个redis。在使用laravel中的队列时,产生冲突干扰。 查找问题原因 在laravel 队列的操作类 从该方法中可以看出Lrarvel队列的redis实现是通过list结构实现的, 所以的redis中list中的key是 至此,两个项目的队列冲突原因就找到了。因为redis队列配置中 因为队列监听 监听的队列名称是由 --queue参数决定的,如果不传就是我们上面设置的默认值,若传了就会根据传入的队列名从前往后优先依次处理,具体见代码 $queue就是--queue=传入的参数,当 $queue不存在是直接调用 至此搞清了队列执行的原理。 解决方法 将queue的配置文件中默认队列修改为不同的名称,比如: 'queue' => laravel1','queue' => laravel2'。 队列监听 最后 遇到问题,莫要病急乱投医。从代码入手,分析理解实现原理,找对点,解决方法也许很简单,希望对大家的学习有所帮助,也希望大家多多支持。Illuminate\Queue\RedisQueue.php
中可以看到pushRaw()
方法:// 将一任务推入队列中public function pushRaw($payload, $queue = null, array $options = []) { $this->getConnection()->rpush($this->getQueue($queue), $payload); return Arr::get(json_decode($payload, true), 'id'); }
rpush(key, value)
是将value推入键值为key的redis队列,key的值则是通过$this->getQueue($queue)
获取到的protected function getQueue($queue) { return 'queues:'.($queue ?: $this->default); }
'queues:'.($queue ?: $this->default);
拼接的,$this->default
的值是 RedisQueue
实例化的时候从config\queue.php
配置中加载的 'queue' => 'default'
,$queue 是添加队列时$this->dispatch( new jobClass()->onQueue($queue) )
传入的。// config\queue.php 文件中的redis配置部分'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => 'default', 'expire' => 60, ],
'queue' => 'default'
都使用的默认的default,所以当共用redis时,默认的队列list 都是'queue:default',所以导致了冲突。Illuminate\Queue\Worker.php
中:protected function getNextJob($connection, $queue) { if (is_null($queue)) { return $connection->pop(); } foreach (explode(',', $queue) as $queue) { if (! is_null($job = $connection->pop($queue))) { return $job; } } }
$connection->pop()
当参数存在时会将参数解析,优先处理排在前面的队列名称,将队列名称传入pop($queue), pop()
会尝试从指定队列或默认队列中获取队列任务// Illuminate\Queue\RedisQueue.phppublic function pop($queue = null) { $original = $queue ?: $this->default; $queue = $this->getQueue($queue); if (! is_null($this->expire)) { $this->migrateAllExpiredJobs($queue); } $job = $this->getConnection()->lpop($queue); if (! is_null($job)) { $this->getConnection()->zadd($queue.':reserved', $this->getTime() + $this->expire, $job); return new RedisJob($this->container, $this, $job, $original); } }
php artisan queue:listen redis --queue=laravel1,syncExpress
您可能感兴趣的文章:
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号