加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

浅谈Laravel队列实现原理解决问题记录

发布时间:2020-12-14 19:55:02 所属栏目:大数据 来源:网络整理
导读:《PHP实战:浅谈Laravel队列实现原理解决问题记录》要点: 本文介绍了PHP实战:浅谈Laravel队列实现原理解决问题记录,希望对您有用。如果有疑问,可以联系我们。 PHP实例 问题 PHP实例公司项目使用Laravel的开发的两个项目在同一个测试服务器部署,公用同一

《PHP实战:浅谈Laravel队列实现原理解决问题记录》要点:
本文介绍了PHP实战:浅谈Laravel队列实现原理解决问题记录,希望对您有用。如果有疑问,可以联系我们。

PHP实例问题

PHP实例公司项目使用Laravel的开发的两个项目在同一个测试服务器部署,公用同一个redis.在使用laravel中的队列时,产生冲突干扰.

PHP实例查找问题原因

PHP实例在laravel 队列的操作类IlluminateQueueRedisQueue.php中可以看到pushRaw()方法:

PHP实例
// 将一任务推入队列中
public function pushRaw($payload,$queue = null,array $options = [])
  {
    $this->getConnection()->rpush($this->getQueue($queue),$payload);
    return Arr::get(json_decode($payload,true),'id');
  }

PHP实例从该方法中可以看出Lrarvel队列的redis实现是通过list结构实现的,rpush(key,value)是将value推入键值为key的redis队列,key的值则是通过$this->getQueue($queue) 获取到的

PHP实例
protected function getQueue($queue)
  {
    return 'queues:'.($queue ?: $this->default);
  }

PHP实例所以的redis中list中的key是 'queues:'.($queue ?: $this->default);拼接的,$this->default 的值是 RedisQueue 实例化的时候从configqueue.php配置中加载的 'queue' => 'default',$queue 是添加队列时$this->dispatch( new jobClass()->onQueue($queue) )传入的.

PHP实例
// configqueue.php 文件中的redis配置部分
'redis' => [
      'driver'   => 'redis','connection' => 'default','queue'   => 'default','expire'   => 60,],

PHP实例至此,两个项目的队列冲突原因就找到了.因为redis队列配置中 'queue' => 'default' 都使用的默认的default,所以当共用redis时,默认的队列list 都是'queue:default',所以导致了冲突.

PHP实例因为队列监听 监听的队列名称是由 --queue参数决定的,如果不传就是我们上面设置的默认值,若传了就会根据传入的队列名从前往后优先依次处理,具体见代码IlluminateQueueWorker.php中:

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;
      }
    }
  }

PHP实例$queue就是--queue=传入的参数,当 $queue不存在是直接调用$connection->pop()当参数存在时会将参数解析,优先处理排在前面的队列名称,将队列名称传入pop($queue),pop()会尝试从指定队列或默认队列中获取队列任务

PHP实例
// IlluminateQueueRedisQueue.php
public 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实例至此搞清了队列执行的原理.

PHP实例解决方法

PHP实例将queue的配置文件中默认队列修改为不同的名称,比如: 'queue' => laravel1','queue' => laravel2'.

PHP实例队列监听 php artisan queue:listen redis --queue=laravel1,syncExpress

PHP实例最后

PHP实例遇到问题,莫要病急乱投医.从代码入手,分析理解实现原理,找对点,解决方法也许很简单,希望对大家的学习有所帮助,也希望大家多多支持编程之家.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读