浅谈Laravel队列实现原理解决问题记录
作者:Dr點燃 发布时间:2024-06-05 15:39:54
问题
公司项目使用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
最后
遇到问题,莫要病急乱投医。从代码入手,分析理解实现原理,找对点,解决方法也许很简单,希望对大家的学习有所帮助,也希望大家多多支持asp之家。
来源:http://www.jianshu.com/p/8e54bd3d7159?utm_source=tuicool&utm_medium=referral
猜你喜欢
- 在pycharm上依次选择打开File->settings->Editor->File andCode Templates
- 概述结构体是由一系列具有相同类型或不同类型的数据构成的数据集合语法定义结构体【标识自定义结构体的名称,在同一个包内不能重复】type 结构名
- python开发者向普通windows用户分享程序,要给程序加图形化的界面(传送门:这可能是最好玩的python GUI入门实例! http
- 靓丽的网页是怎样生成的?也许您会脱口而出,当然是自己设计出来的。没错!不过这其中也有网页制作工具的一部分功劳,因为功能强大的网页制作工具可以
- SQL防注入代码一<?php /** * 防sql注入 * @author: zhuyubing@gmail.com * */ /**
- “MySQL是一个功能齐全的关系数据库管理系统(RDBMS),可以与Oracle DB和Microsoft的SQL Server竞争。MyS
- 需求:小程序端拍照调用python训练好的图片分类模型。实现图片分类识别的功能。微信小程序端:重点在chooseImage函数中,根据图片路
- 本文简介前段时间,黄同学写了一篇《MySQL窗口实战》文章(文章如下),但是里面大多数是以实战练习为主,没有做详细的解释。传送门:MySQL
- 最佳方式:根据map的长度,新建一个数组,遍历map逐个压入方法1(效率很高):func getKeys1(m map[int]int) [
- 本文总结分析了MySQL查询优化的技巧。分享给大家供大家参考,具体如下:熟悉SQL语句的人都清楚,如果要对一个任务进行操作的话,SQL语句可
- 本文实例为大家分享了python利用tkinter实现屏保的具体代码,供大家参考,具体内容如下import randomimport tki
- 网上大部分教程都写的直接关闭界面,我摸索出来一个方法:同时绑定两个事件例:#自己方法self.registerButton.clicked.
- 在安装数据库的时候出现了如下错误:解决办法如下:1.在bin目录下 输入:kill -s 9 9907 再输入:ps
- 一.下载安装包官网下载:python 3.6.0打开链接滑到页面最下方二. 开始安装1.双击下载好的安装文件python-3.6.0-amd
- 字符串中字符大小写的变换1. str.lower() //小写>>> 'SkatE'
- SqlBulkCopy 来自数据源的 String 类型的给定值不能转换为指定目标列的类型 nvarchar。 在网上找了下,大都说是因为数
- ASP与MySQL的连接ASP和MySQL连接目前有两种方法:一种方法是使用MySQLX之类的组件,不过这种连接方法需要支付一定的费用;另外
- LSTM简介1、RNN的梯度消失问题在过去的时间里我们学习了RNN循环神经网络,其结构示意图是这样的:其存在的最大问题是,当w1、w2、w3
- 1.单继承父类也叫基类子类也叫派生类如下所示,继承的关系:继承的书写格式:class 子类(父类):方法实例:class Animal: &
- 本文实例讲述了Python实现的微信公众号群发图片与文本消息功能。分享给大家供大家参考,具体如下:在微信公众号开发中,使用api都要附加ac