广告
返回顶部
首页 > 资讯 > 精选 >laravel源码分析队列Queue方法怎么用
  • 242
分享到

laravel源码分析队列Queue方法怎么用

2023-06-29 21:06:22 242人浏览 八月长安
摘要

本篇内容介绍了“laravel源码分析队列Queue方法怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!队列任务的创建先通过命令创建一个

本篇内容介绍了“laravel源码分析队列Queue方法怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

队列任务的创建

先通过命令创建一个 Job 类,成功之后会创建如下文件 laravel-src/laravel/app/Jobs/DemoJob.PHP

php artisan make:job DemoJob > Job created successfully.

下面我们来分析一下 Job 类的具体生成过程。

执行 php artisan make:job DemoJob 后,会触发调用如下方法。

laravel-src/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php

protected function reGISterJobMakeCommand(){    $this->app->singleton('command.job.make', function ($app) {        return new JobMakeCommand($app['files']);    });}

接着我们来看下 JobMakeCommand 这个类,这个类里面没有过多的处理逻辑,处理方法在其父类中。

 class JobMakeCommand extends GeneratorCommand

我们直接看父类中的处理方法,GeneratorCommand->handle(),以下是该方法中的主要方法。

public function handle(){    // 获取类名    $name = $this->qualifyClass($this->getNameInput());    // 获取文件路径    $path = $this->getPath($name);    // 创建目录和文件    $this->makeDirectory($path);    // buildClass() 通过模板获取新类文件的内容    $this->files->put($path, $this->buildClass($name));    // $this->type 在子类中定义好了,例如 JobMakeCommand 中 type = 'Job'    $this->info($this->type.' created successfully.');}

方法就是通过目录和文件,创建对应的类文件,至于新文件的内容,都是基于已经设置好的模板来创建的,具体的内容在 buildClass($name) 方法中。

 protected function buildClass($name){    // 得到类文件模板,getStub() 在子类中有实现,具体看 JobMakeCommand     $stub = $this->files->get($this->getStub());    // 用实际的name来替换模板中的内容,都是关键词替换    return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);}

获取模板文件

protected function getStub(){    return $this->option('sync')                    ? __DIR__.'/stubs/job.stub'                    : __DIR__.'/stubs/job-queued.stub';}

job.stub

 <?phpnamespace DummyNamespace; use Illuminate\Bus\Queueable;use Illuminate\Foundation\Bus\Dispatchable; class DummyClass{    use Dispatchable, Queueable;         public function __construct()    {        //    }         public function handle()    {        //    }}

job-queued.stub

<?phpnamespace DummyNamespace; use Illuminate\Bus\Queueable;use Illuminate\Queue\SerializesModels;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Foundation\Bus\Dispatchable; class DummyClass implements ShouldQueue{    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;         public function __construct()    {        //    }         public function handle()    {        //    }}

下面看一下前面我们创建的一个Job类,DemoJob.php,就是来源于模板 job-queued.stub。

<?phpnamespace App\Jobs;use Illuminate\Bus\Queueable;use Illuminate\Queue\SerializesModels;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Foundation\Bus\Dispatchable;class DemoJob implements ShouldQueue{    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;         public function __construct()    {        //    }         public function handle()    {        //    }}

至此,我们已经大致明白了队列任务类是如何创建的了。下面我们来分析下其是如何生效运行的。

队列任务的分发

任务类创建后,我们就可以在需要的地方进行任务的分发,常见的方法如下:

DemoJob::dispatch(); // 任务分发DemoJob::dispatchNow(); // 同步调度,队列任务不会排队,并立即在当前进程中进行

下面先以 dispatch() 为例分析下分发过程。

trait Dispatchable{    public static function dispatch()    {        return new PendingDispatch(new static(...func_get_args()));    }}
 class PendingDispatch{    protected $job;     public function __construct($job)    {   echo '[Max] ' . 'PendingDispatch ' . '__construct' . PHP_EOL;        $this->job = $job;    }    public function __destruct()    {   echo '[Max] ' . 'PendingDispatch ' . '__destruct' . PHP_EOL;        app(Dispatcher::class)->dispatch($this->job);    }}

重点是 app(Dispatcher::class)->dispatch($this->job) 这部分。

我们先来分析下前部分 app(Dispatcher::class),它是在 laravel 框架中自带的 BusServiceProvider 中向 $app 中注入的。

class BusServiceProvider extends ServiceProvider implements DeferrableProvider{    public function register()    {        $this->app->singleton(Dispatcher::class, function ($app) {            return new Dispatcher($app, function ($connection = null) use ($app) {                return $app[QueueFactoryContract::class]->connection($connection);            });        });    }}

看一下 Dispatcher 的构造方法,至此,我们已经知道前半部分 app(Dispatcher::class) 是如何来的了。

class Dispatcher implements QueueingDispatcher{    protected $container;    protected $pipeline;    protected $queueResolver;     public function __construct(Container $container, Closure $queueResolver = null)    {        $this->container = $container;                $this->queueResolver = $queueResolver;        $this->pipeline = new Pipeline($container);    }    public function dispatch($command)    {        if ($this->queueResolver && $this->commandShouldBeQueued($command)) {        // 将 $command 存入队列            return $this->dispatchToQueue($command);        }        return $this->dispatchNow($command);    }}

BusServiceProvider 中注册了 Dispatcher::class ,然后 app(Dispatcher::class)->dispatch($this->job) 调用的即是 Dispatcher->dispatch()。

 public function dispatchToQueue($command){    // 获取任务所属的 connection    $connection = $command->connection ?? null;        $queue = call_user_func($this->queueResolver, $connection);    if (! $queue instanceof Queue) {        throw new RuntimeException('Queue resolver did not return a Queue implementation.');    }    // 我们创建的DemoJob无queue方法,则不会调用    if (method_exists($command, 'queue')) {        return $command->queue($queue, $command);    }    // 将 job 放入队列    return $this->pushCommandToQueue($queue, $command);}protected function pushCommandToQueue($queue, $command){    // 在指定了 queue 或者 delay 时会调用不同的方法,基本大同小异    if (isset($command->queue, $command->delay)) {        return $queue->laterOn($command->queue, $command->delay, $command);    }    if (isset($command->queue)) {        return $queue->pushOn($command->queue, $command);    }    if (isset($command->delay)) {        return $queue->later($command->delay, $command);    }    // 此处我们先看最简单的无参数时的情况,调用push()    return $queue->push($command);}

笔者的配置是 QUEUE_CONNECTION=Redis ,估以此来分析,其他类型的原理基本类似。

配置的是 redis 时, $queue 是 RedisQueue 实例,下面我们看下 RedisQueue->push() 的内容。

Illuminate/Queue/RedisQueue.php

public function push($job, $data = '', $queue = null){        // 将任务和数据存入队列    return $this->pushRaw($this->createPayload($job, $this->getQueue($queue), $data), $queue);}public function pushRaw($payload, $queue = null, array $options = []){    // 写入redis中    $this->getConnection()->eval(        luaScripts::push(), 2, $this->getQueue($queue),        $this->getQueue($queue).':notify', $payload    );    // 返回id    return JSON_decode($payload, true)['id'] ?? null;}

“laravel源码分析队列Queue方法怎么用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: laravel源码分析队列Queue方法怎么用

本文链接: https://www.lsjlt.com/news/326345.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • laravel源码分析队列Queue方法怎么用
    本篇内容介绍了“laravel源码分析队列Queue方法怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!队列任务的创建先通过命令创建一个...
    99+
    2023-06-29
  • laravel源码分析队列Queue方法示例
    目录前言队列任务的创建队列任务的分发前言 队列 (Queue) 是 laravel 中比较常用的一个功能,队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短 Web 请求...
    99+
    2022-11-13
  • Netty分布式flush方法刷新buffer队列源码分析
    本文小编为大家详细介绍“Netty分布式flush方法刷新buffer队列源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Netty分布式flush方法刷新buffer队列源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入...
    99+
    2023-06-29
  • 【Queue】- 从源码分析PriorityQueue及其常用方法
    文章目录 PriorityQueue基础知识 概述 PriorityQueue内部结构 PriorityQueue扩容操作 PriorityQueue队列的构造方法 PriorityQue...
    99+
    2023-08-17
    java 源码 优先级队列 PriorityQueue Queue
  • Netty分布式flush方法刷新buffer队列源码剖析
    目录flush方法这里最终会调用AbstractUnsafe的flush方法跟进addFlush方法回到addFlush方法回到AbstractUnsafe的flush方法我们重点关...
    99+
    2022-11-13
  • 怎么用c#写开源分布式消息队列equeue
    这篇文章主要介绍“怎么用c#写开源分布式消息队列equeue”,在日常操作中,相信很多人在怎么用c#写开源分布式消息队列equeue问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用c#写开源分布式消息队列...
    99+
    2023-06-17
  • 怎么用源代码分析FileZilla
    本篇文章给大家分享的是有关怎么用源代码分析FileZilla,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。FileZilla是一种快速、可信赖的FTP客户端以及服务器端开放源代...
    99+
    2023-06-16
  • 怎么用源码分析Play Framework hotswap
    这期内容当中小编将会给大家带来有关怎么用源码分析Play Framework hotswap,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Play Framework hotswap的卖点就在于 hot ...
    99+
    2023-06-17
  • Python之列表append()方法使用实例代码分析
    这篇文章主要介绍“Python之列表append()方法使用实例代码分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python之列表append()方法使用实例代码分析”文章能帮助大家解决问题。...
    99+
    2023-07-04
  • 怎么用Hadoop源码分析心跳机制
    这篇文章将为大家详细讲解有关怎么用Hadoop源码分析心跳机制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一.心跳机制 hadoop集群是master/slave模式,master包括Na...
    99+
    2023-06-17
  • 怎么用java源代码分析jvm.dll装载过程
    怎么用java源代码分析jvm.dll装载过程,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。简述众所周知java.exe是java class文件的执行程序,但...
    99+
    2023-06-03
  • 怎么用源码分析在linux上符号表的读取
    这期内容当中小编将会给大家带来有关怎么用源码分析在linux上符号表的读取,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。通常我们使用jmap,jstack 去检查堆栈信息的时候,是不会使用-f参数的,但有...
    99+
    2023-06-17
  • 怎么分析分布式事务常用解决方法
    这期内容当中小编将会给大家带来有关怎么分析分布式事务常用解决方法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。分布式事务的解决方法方案1:全局事务(DTP模型)全局事务基于DTP模型实现。DTP是由X/O...
    99+
    2023-06-04
  • 怎么使用Java方法调用解析静态分派和动态分派
    这篇“怎么使用Java方法调用解析静态分派和动态分派”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用Java方法调用解...
    99+
    2023-07-02
  • win8磁盘占用100怎么办 win8磁盘占用率100%问题分析及解决方法
    之前有不少Win8用户反馈,Win8磁盘使用率经常处于100%,之前也一直没有找到有效的解决办法。业界一直称Win8磁盘占用100是一个已知Wn8问题,我们只能等待微软更新来解决,并且不少朋友称Win8磁盘...
    99+
    2022-06-04
    磁盘 解决方法 占用率
  • 怎么使用SAP SAT事务码对通过浏览器启动的应用的性能测量和分析方式
    怎么使用SAP SAT事务码对通过浏览器启动的应用的性能测量和分析方式,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。三个产品都有登录语言的选择:CRMC4C:Hybris:...
    99+
    2023-06-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作