Laravel中使用Queue的最基本操作教程
前言
laravel中的队列服务跟其他队列服务也没有什么不同,都是最符合人类思维的最简单最普遍的流程:有一个地方存放队列信息,一个PHP进程在运行时将任务写入,另外一个PHP守护进程轮询队列信息,将达到执行要求的任务执行并删除。由于PHP是url驱动的同步语言,本身是阻塞的,所以laravel提供一个守护进程工具来查询并执行队列信息也就不足为奇了。
这两天初次接触Laravel的队列,也是搞了好一会。。。一番折腾下来还是感慨对Laravel不得其门,文档写的相对简单和概括,看源码又有些力不从心(不过看源码慢慢调试验证还是最可靠的)。
下面是我的一个简单Demo,仅仅使用了队列的最基本操作,偏高级的操作需要再去好好时间一番:)
和我一样入门Laravel的队列有些困难的同学可以交流一下。
配置
添加Redis包
在composer.json中require部分加入"predis/predis":"~1.0",,然后composerup更新一下即可。
database.php
在database.php配置文件中对redis数据库部分进行配置,默认有一个default连接,就用这个好了:)
根据这个默认连接中需要的配置项,编辑.env配置文件,将其中的REDIS_HOST、REDIS_PASSWORD、REDIS_PORT填写成自己服务器中Redis的相应值。
queue.php
首先需要去.env中配置QUEUE_DRIVER,因为现在打算用Redis,所以配置成redis。
接着配置queue.php里connections部分的redis连接,其中connection对应的值就是database.php中redis的那个default连接。
任务类
接下来就是写实际的操作类了,Laravel提供了artisan命令简化创建任务类:
phpartisanmake:jobDemo
在app目录下会生成Jobs目录,里面已经有了Demo.php任务类。
Lumen可没有这个artisan命令,不过也很方便,默认会有一个ExampleJob.php已经写好了,拷贝一份改个名字即可。
先写个简单的日志输出测试一下好了,在handle方法中:
Log::info('Hello,queue');
发放任务
现在写个入口函数,推送任务到队列中。使用辅助函数dispatch():
Laravel中使用如下方式:
Demo::dispatch();
Lumen中使用如下方式:
dispatch(newDemo);
开启队列
顺利的话,这是最后一步了。命令行中执行:
phpartisanqueue:listen--queue=default
它会监听队列,并输出简单的执行情况,比如:
[2017-11-0702:12:47]Processing:App\Jobs\Demo [2017-11-0702:12:47]Processed:App\Jobs\Demo
没啥问题后就可以让这个队列脚本执行在后台:
phpartisanqueue:work--daemon--quiet--queue=default1>>/dev/null2>&1
进阶一下:)
推送到队列中时,一般会有传参的需求,那这里怎么传呢?
参数传递
传入
在入口函数中传入参数方式如下:
Laravel中使用如下方式:
$param='Stephen'; Demo::dispatch($param);
Lumen中使用如下方式:
$param='Stephen'; dispatch(newDemo($param));
接收
在任务类中接收参数方式如下:
protected$param; /** *Createanewjobinstance. * *@returnvoid */ publicfunction__construct($param) { $this->param=$param; } /** *Executethejob. * *@returnvoid */ publicfunctionhandle() { Log::info('Hello,'.$this->param); }
初次尝试到此为止,还有许多高级用法,比如延迟分发、错误处理、优先级、失败处理等,后续会继续写:)
多队列
这是一个必然需要考虑到的问题,我不可能将所有任务都放在一个叫default的队列中,这样不容易对队列进行管理。
要指定不同的队列,非常简单,在dispatch()后紧接着跟上onQueue()方法即可:
Demo::dispatch()->onQueue('emails');
不对啊,我好像没有定义过这个叫emails的queue。嗯,自然需要做出一点改动,在queue.php配置文件中的redis配置queue从default改为{default},这样做的效果就是队列的名称可以从运行的时候动态拿到,而不是写死的。
如果使用Lumen框架,那么直接这么写会报错:CalltoamemberfunctiononQueue()onstring。
原因在于Lumen的Job基类中并没有使用Illuminate\Foundation\Bus\Dispatchable这个trait,而是直接使用Illuminate\Bus\Queueable中的onQueue()方法。
那么现在就很清楚了,我们的Job类使用了Illuminate\Bus\Queueable这个trait,所以需要在Job类上调用这个onQueue()方法。
$job=newXXXJob(); dispatch($job->onQueue('queue-name'));
当我们在开启队列的时候:
phpartisanqueue:work--queue=emails
这里指定的队列名emails和dispatch时指定的队列名保持一致即可。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。
参考链接
Laravel官方文档