资讯专栏INFORMATION COLUMN

Laravel 写个 Queue 怎么这么难

RebeccaZhong / 1326人阅读

摘要:可没有这个命令,不过也很方便,默认会有一个已经写好了,拷贝一份改个名字即可。如果使用框架,那么直接这么写会报错。原因在于的基类中并没有使用这个,而是直接使用中的方法。

这两天初次接触 Laravel 的队列,也是搞了好一会。。。一番折腾下来还是感慨对 Laravel 不得其门,文档写的相对简单和概括,看源码又有些力不从心(不过看源码慢慢调试验证还是最可靠的)。

下面是我的一个简单 Demo,仅仅使用了队列的最基本操作,偏高级的操作需要再去好好时间一番 :)

和我一样入门 Laravel 的队列有些困难的同学可以交流一下。

配置 添加 Redis 包

composer.jsonrequire 部分加入 "predis/predis": "~1.0",,然后 composer up 更新一下即可。

database.php

database.php 配置文件中对 redis 数据库部分进行配置,默认有一个 default 连接,就用这个好了:)

根据这个默认连接中需要的配置项,编辑 .env 配置文件,将其中的 REDIS_HOSTREDIS_PASSWORDREDIS_PORT 填写成自己服务器中 Redis 的相应值。

queue.php

首先需要去 .env 中配置 QUEUE_DRIVER,因为现在打算用 Redis,所以配置成 redis

接着配置 queue.php 里 connections 部分的 redis 连接,其中 connection 对应的值就是 database.php 中 redis 的那个 default 连接。

任务类

接下来就是写实际的操作类了,Laravel 提供了 artisan 命令简化创建任务类:

php artisan make:job Demo

app 目录下会生成 Jobs 目录,里面已经有了 Demo.php 任务类。

Lumen 可没有这个 artisan 命令,不过也很方便,默认会有一个 ExampleJob.php 已经写好了,拷贝一份改个名字即可。

先写个简单的日志输出测试一下好了,在 handle 方法中:

Log::info("Hello, queue");
发放任务

现在写个入口函数,推送任务到队列中。使用辅助函数 dispatch()

Laravel 中使用如下方式:

Demo::dispatch();

Lumen 中使用如下方式:

dispatch(new Demo);
开启队列

顺利的话,这是最后一步了。命令行中执行:

php artisan queue:listen --queue=default

它会监听队列,并输出简单的执行情况,比如:

[2017-11-07 02:12:47] Processing: AppJobsDemo
[2017-11-07 02:12:47] Processed:  AppJobsDemo

没啥问题后就可以让这个队列脚本执行在后台:

php artisan queue:work --daemon --quiet --queue=default 1>> /dev/null 2>&1 &

进阶一下 :)

推送到队列中时,一般会有传参的需求,那这里怎么传呢?

参数传递 传入

在入口函数中传入参数方式如下:

Laravel 中使用如下方式:

$param = "Stephen";
Demo::dispatch($param);

Lumen 中使用如下方式:

$param = "Stephen";
dispatch(new Demo($param));
接收

在任务类中接收参数方式如下:

protected $param;

/**
 * Create a new job instance.
 *
 * @return void
 */
public function __construct($param)
{
    $this->param = $param;
}

/**
 * Execute the job.
 *
 * @return void
 */
public function handle()
{
    Log::info("Hello, " . $this->param);
}

初次尝试到此为止,还有许多高级用法,比如延迟分发、错误处理、优先级、失败处理等,后续会继续写 :)

多队列

这是一个必然需要考虑到的问题,我不可能将所有任务都放在一个叫 default 的队列中,这样不容易对队列进行管理。

要指定不同的队列,非常简单,在 dispatch() 后紧接着跟上 onQueue() 方法即可:

Demo::dispatch()->onQueue("emails");

不对啊,我好像没有定义过这个叫 emails 的 queue。嗯,自然需要做出一点改动,在 queue.php 配置文件中的 redis 配置 queuedefault 改为 {default},这样做的效果就是队列的名称可以从运行的时候动态拿到,而不是写死的。

如果使用 Lumen 框架,那么直接这么写会报错:Call to a member function onQueue() on string

原因在于 Lumen 的 Job 基类中并没有使用 IlluminateFoundationBusDispatchable 这个 trait,而是直接使用 IlluminateBusQueueable 中的 onQueue() 方法。

那么现在就很清楚了,我们的 Job 类使用了 IlluminateBusQueueable 这个 trait,所以需要在 Job 类上调用这个 onQueue() 方法。

$job = new XXXJob();
dispatch($job->onQueue("queue-name"));

当我们在开启队列的时候:

php artisan queue:work --queue=emails

这里指定的队列名 emails 和 dispatch 时指定的队列名保持一致即可。

参考链接

Laravel 官方文档

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26253.html

相关文章

  • 献给虚拟主机 Laravel 4 用户: 全功能 MySQL 队列驱动器 L4mysqlqueue

    摘要:几小时前刚刚发布的为队列功能提供了官方原生的驱动器,完全取代了本软件包的功能。不过这也并不意味着就是虚拟主机没戏,必须云主机起跳的小网站杀手。性能确实低下受制于,绝对禁止用于大数量高密度任务的场合。虚拟主机肯定不会提供。 几小时前刚刚发布的 Larevel 5.0 为队列功能提供了官方原生的database驱动器,完全取代了本软件包的功能。 对于Laravel 5及以上版本,本文的内...

    missonce 评论0 收藏0
  • 写个博客程序,基于Laravel5.1开发

    摘要:话说也是换过好多程序,等都有尝试过。更像是一个小型,内容型网站的瑞士军刀。之所以不用它就是想换个程序。其实作为博客很不错的编辑器,速度快,轻量。但不安分的我决定还是自己写一个吧。权限管理缓存等还没有完善,感受就是自己就是青铜五的渣渣水平。 话说也是换过好多程序,WordPress、HEXO、Typecho等都有尝试过。WordPress更像是一个小型CMS,内容型网站的瑞士军刀。之所以...

    springDevBird 评论0 收藏0
  • 为什么 Laravel 会重复执行同一个队列任务?

    摘要:把因执行超时的队列从集合重新到当前执行的队列中。从要执行的队列中取任务可以看到在取要执行的队列的时候,同时会放一份到一个有序集合中,并使用过期时间戳作为分值。 (原文链接:https://blog.tanteng.me/2017/...) 在 Laravel 中使用 Redis 处理队列任务,框架提供的功能非常强大,但是最近遇到一个问题,就是发现一个任务被多次执行,这是为什么呢? 先说...

    vboy1010 评论0 收藏0
  • Laravel 队列服务

    摘要:按照配置文件注册一个默认连接方式在此使用注册队列各种命令队列连接重启等。上面任务进入队列的整个流程就明白了。 showImg(https://segmentfault.com/img/bVFvpd?w=980&h=274); 看完文档 后总想知道是怎么样一个开始,又是怎样的一个结束!图片来源 QueueServiceProvider Laravel 各种服务的注册大多都是通过各种 Se...

    Caizhenhao 评论0 收藏0
  • 剖析Laravel队列系统--初探

    摘要:配有内置的队列系统,可帮助您在后台运行任务,并通过简单的来配置系统在不同情况下起作用。您可以在中管理队列配置,默认情况下它有使用不同队列驱动的几个连接,您可以看到项目中可以有多个队列连接,也可以使用多个队列驱动程序。 原文链接https://divinglaravel.com/queue-system/before-the-dive Laravel receives a request...

    pubdreamcc 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<