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


Posted in PHP onAugust 19, 2017

问题

公司项目使用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

最后

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

PHP 相关文章推荐
apache+mysql+php+ssl服务器之完全安装攻略
Sep 05 PHP
PHP6 mysql连接方式说明
Feb 09 PHP
PHP开发环境配置(MySQL数据库安装图文教程)
Apr 28 PHP
php使用异或实现的加密解密实例
Sep 04 PHP
PHP与Java进行通信的实现方法
Oct 21 PHP
ThinkPHP结合ajax、Mysql实现的客户端通信功能代码示例
Jun 23 PHP
PHP实现生成唯一编号(36进制的不重复编号)
Jul 01 PHP
php中mkdir函数用法实例分析
Nov 15 PHP
PHP中imagick函数的中文解释
Jan 21 PHP
WordPress中邮件的一些修改和自定义技巧
Dec 15 PHP
php使用PDO从数据库表中读取数据的实现方法(必看)
Jun 02 PHP
PHP实现双链表删除与插入节点的方法示例
Nov 11 PHP
yii2 commands模式以及配置crontab定时任务的方法
Aug 19 #PHP
利用 fsockopen() 函数开放端口扫描器的实例
Aug 19 #PHP
PHPMailer使用QQ邮箱实现邮件发送功能
Aug 18 #PHP
PHP实现自动发送邮件功能代码(qq 邮箱)
Aug 18 #PHP
详解PHP如何更好的利用PHPstorm的自动提示
Aug 18 #PHP
Laravel学习教程之本地化模块
Aug 18 #PHP
PDO操作MySQL的基础教程(推荐)
Aug 18 #PHP
You might like
Smarty模板快速入门
2007/01/04 PHP
CodeIgniter配置之SESSION用法实例分析
2016/01/19 PHP
浅谈PHP发送HTTP请求的几种方式
2017/07/25 PHP
php微信公众号开发之二级菜单
2018/10/20 PHP
使用Zookeeper分布式部署PHP应用程序
2019/03/15 PHP
PHP 计算至少是其他数字两倍的最大数的实现代码
2020/05/26 PHP
ajax无刷新动态调用股票信息(改良版)
2008/11/01 Javascript
js数组的操作详解
2013/03/27 Javascript
删除select中所有option选项jquery代码
2013/08/12 Javascript
Jquery实现仿腾讯娱乐频道焦点图(幻灯片)特效
2015/03/06 Javascript
Jquery实现上下移动和排序代码
2016/10/17 Javascript
JS开发中百度地图+城市联动实现实时触发查询地址功能
2017/04/13 Javascript
vue.js实现刷新当前页面的方法教程
2017/07/05 Javascript
提升页面加载速度的插件InstantClick
2017/09/12 Javascript
vue-cli项目中怎么使用mock数据
2017/09/27 Javascript
在vue中添加Echarts图表的基本使用教程
2017/11/22 Javascript
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
2018/07/04 Javascript
Vue中通过Vue.extend动态创建实例的方法
2019/08/13 Javascript
OpenLayers加载缩放控件使用方法详解
2020/09/25 Javascript
linux系统使用python监测系统负载脚本分享
2014/01/15 Python
利用numpy和pandas处理csv文件中的时间方法
2018/04/19 Python
python统计多维数组的行数和列数实例
2018/06/23 Python
python实现归并排序算法
2018/11/22 Python
django模板结构优化的方法
2019/02/28 Python
python实现录屏功能(亲测好用)
2020/03/02 Python
如何通过python计算圆周率PI
2020/11/11 Python
Python实现曲线拟合的最小二乘法
2021/02/19 Python
CSS3对背景图片的裁剪及尺寸和位置的设定方法
2016/03/07 HTML / CSS
新加坡第一的杂货零售商:NTUC FairPrice
2020/12/05 全球购物
求职推荐信
2013/10/28 职场文书
加强干部作风建设整改方案
2014/10/24 职场文书
群众路线专项整治工作情况报告
2014/10/28 职场文书
初中生300字旷课检讨书
2014/11/19 职场文书
2015年学校安全工作总结
2015/04/22 职场文书
2019年XX公司的晨会制度及流程!
2019/07/23 职场文书
Django框架之路由用法
2022/06/10 Python