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

 更新时间:2017年08月19日 20:10:04   作者:Dr點燃  
本篇文章主要介绍了浅谈Laravel队列实现原理解决问题记录,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

问题

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

查找问题原因

在laravel 队列的操作类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');
  }

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

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

所以的redis中list中的key是 '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,
    ],

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

因为队列监听 监听的队列名称是由 --queue参数决定的,如果不传就是我们上面设置的默认值,若传了就会根据传入的队列名从前往后优先依次处理,具体见代码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;
      }
    }
  }

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

// Illuminate\Queue\RedisQueue.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);
    }
  }

至此搞清了队列执行的原理。

解决方法

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

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

最后

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

相关文章

  • thinkPHP实现的省市区三级联动功能示例

    thinkPHP实现的省市区三级联动功能示例

    这篇文章主要介绍了thinkPHP实现的省市区三级联动功能,详细分析了thinkPHP实现省市区三级联动功能的详细步骤与相关操作技巧,需要的朋友可以参考下
    2017-05-05
  • Yii2针对指定url的生成及图片等的引入方法小结

    Yii2针对指定url的生成及图片等的引入方法小结

    这篇文章主要介绍了Yii2针对指定url的生成及图片等的引入方法,针对常用的URL格式及图片路径操作结合实例进行了对比分析,需要的朋友可以参考下
    2016-07-07
  • yii2-GridView在开发中常用的功能及技巧总结

    yii2-GridView在开发中常用的功能及技巧总结

    本篇文章主要介绍了yii2-GridView在开发中常用的功能及技巧总结,数据网格或者说 GridView 小部件是Yii中最强大的部件之一。有兴趣的可以了解一下。
    2017-01-01
  • ThinkPHP独立分组使用的注意事项

    ThinkPHP独立分组使用的注意事项

    这篇文章主要介绍了ThinkPHP独立分组使用的注意事项,针对独立分组的目录结构与分组之间的相互调用进行了较为深入的分析,并指出了使用时的注意事项,需要的朋友可以参考下
    2014-11-11
  • Laravel 前端资源配置教程

    Laravel 前端资源配置教程

    今天小编就为大家分享一篇Laravel 前端资源配置教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-10-10
  • php arsort 数组降序排序详细介绍

    php arsort 数组降序排序详细介绍

    php arsort函数用于将数组中的元素按照降序进行排序,如果排序成功则返回true,否则返回false,本文章向大家讲解arsort函数的基本语法及使用实例,需要的朋友可以参考下
    2016-11-11
  • 新浪SAE搭建PHP项目教程

    新浪SAE搭建PHP项目教程

    这篇文章主要介绍了新浪SAE搭建PHP项目教程,图文并茂,需要的朋友可以参考下
    2015-01-01
  • php集成动态口令认证

    php集成动态口令认证

    这篇文章主要为大家详细介绍了php集成动态口令认证,动态口令采用一次一密、用过密码作废的方式来提高安全性能,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Laravel框架集成UEditor编辑器的方法图文与实例详解

    Laravel框架集成UEditor编辑器的方法图文与实例详解

    这篇文章主要介绍了Laravel框架集成UEditor编辑器的方法,结合图文与实例形式详细分析了Laravel框架整合集成UEditor编辑器的相关操作步骤与具体实现技巧,需要的朋友可以参考下
    2019-04-04
  • Laravel服务容器绑定的几种方法总结

    Laravel服务容器绑定的几种方法总结

    这篇文章主要给大家介绍了关于Laravel服务容器绑定的几种方式,文中通过示例代码介绍的非常详细,对大家学习或者使用Laravel具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-06-06

最新评论