专栏首页编程乐园浅谈Laravel队列实现原理解决问题记录

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

问题

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

查找问题原因

在laravel 队列的操作类IlluminateQueueRedisQueue.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) )传入的。

// configqueue.php 文件中的redis配置部分

'redis' => [

'driver' => 'redis',

'connection' => 'default',

'queue' => 'default',

'expire' => 60,

],

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

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

// 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);

}

}

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

解决方法

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

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

最后

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

原文链接:https://www.blog.zirun.me/php/4630.html

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 今日推荐:awesome-architecture

    但是这条路还是有很多人走,而且也留下了相应的封神之法,今天推荐的就是一个相当详细的架构师框架学习图。内容很充实,看目录的时候,滚动条滚了很多次!学习起来肯定也不...

    仇诺伊
  • [译]Laravel 5.0 之命令及处理程序

    本文译自 Matt Stauffer 的系列文章. ---- 本文中涉及的新功能都是关于 Commands 的,这些特性在 Laravel 旧版本中已经有了,但...

    小李刀刀
  • PHPer面试指南-laravel 篇

    码农编程进阶笔记
  • 两天时间面试9家拿到7家offer 我都遇到哪些奇葩问题

    这两天请了两天假,出去看了看外面的招聘市场。两天时间面试了9家公司,成功拿到6家offer,这里总结一下,个人在面试中遇到的一些问题,不是很全,有一些忘记了。这...

    A梦多啦A
  • Laravel API 开发推荐阅读清单

    社区优秀文章 Laravel 5.5+passport 放弃 dingo 开发 API 实战,让 API 开发更省心 - 自造车轮。 API 文档神器 Swag...

    guanguans
  • 【阅读清单】系列文章清单列表(二)

    动手学深度学习 https://cloud.tencent.com/developer/inventory/1621"

    云加社区
  • 全局梳理、分析、总结 laravel 的核心概念

    Laravel 是 Taylor Otwell 开发的一款基于 PHP 语言的 Web 开源框架,采用了 MVC 的架构模式。

    八点半的Bruce、D
  • Laravel 队列使用的实现

    Laravel是一种类似ThinkPHP的php框架,封装的诸多功能可以很方便的使用。队列Queue便是其中之一。

    砸漏
  • Laravel框架关键技术解析

    1.index.php:自动加载函数的添加、服务容器实例化与服务注册、路由加载、请求实例化与路由分发、响应生成与发送

    硬核项目经理
  • 【云+社区年度征文】2020征文活动获奖名单公布

    由腾讯云+社区主办的云+社区 2020 年度征文活动在2020年12月31号圆满的落下帷幕。年度征文活动自2020年11月发布后,吸引了众多社区内的小伙伴。经过...

    云加社区
  • 浅谈laravel框架sql中groupBy之后排序的问题

    groupBy中的字段必须是select的字段,并且orderBy从句也必须是select的字段。但是如果select的字段使用聚合函数呢?抱着

    砸漏
  • 浅谈laravel框架与thinkPHP框架的区别

    2、在Laravel框架里,由于其考虑到了跨站请求伪造, 所以如果使用form表单以post方式进行传值时,如果不再form表单中加入{{csrf_field(...

    砸漏
  • CentOS Supervisord守护进程实现Laravel异步队列任务

    Supervisor是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统。它可以很...

    子润先生
  • laravel Task Scheduling(任务调度)在windows下的使用详解

    laravel的任务调度是很好用的,因为Laravel提供了平滑而又富有表现力地调度器,并且服务器上只需要一个Cron条目即可,这使我们从编写手动写cronta...

    砸漏
  • 浅析 Laravel 底层原理:契约(Contracts)

    Laravel 中的契约是指框架提供的一系列定义核心服务的接口(interface)。

    码农编程进阶笔记
  • 关于laravel 日志写入失败问题汇总

    项目部署到Linux 服务器上后有时会出现 每日日志无法写入的问题。由此汇总一下常出现的问题及解决方式。

    砸漏
  • 「冰河技术」部分精华文章目录汇总

    个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准...

    冰河
  • 面试携程 我都遇到了这些问题

    这两天请了两天假,出去看了看外面的招聘市场。两天时间差不多面了10家公司,成功拿到7家offer,这里总结一下,个人在面试中遇到的一些问题,不是很全,有一些忘记...

    A梦多啦A
  • 后台开发常问面试题集锦(问题搬运工,文末附问题链接)

    Synchronized(对象锁)和Static Synchronized(类锁)的区别

    Java架构技术

扫码关注云+社区

领取腾讯云代金券