laravel队列(queue)的正确使用方法
1、首先检查自己的环境是否符合要求[其中我用php7是因为我系统里面有多个php版本] php -v composer --version
2、接着使用composer初始化一个基于laravel5.5版本的项目 composer create-project laravel/laravel laravel-queue --prefer-dist "5.5.*"
3、为了演示队列的使用,我尺攵跋赈们将使用基于数据库驱动的队列,但是真实项目建议使用redis或者rabbitmq或者fakfa等专业的队列服务.修改项目中的.env配置文件 DB_HOST=剞麽苍足数据库主 DB_PORT=数据库端 DB_DATABASE=数据库 DB_USERNAME=数据库用 DB_PASSWORD=数据库密码 QUEUE_DRIVER=database 并创建laravel-queue数据库 CREATE DATABASE `laravel-queue` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
4、准备工作做好了,那我们就开始写代码了,我们使用laravel提供的脚手架生成处理队列的任务类DemoQueue php artisan make:job DemoQueue这个时候会在你的项目下面多了一个Jobs目录,最终生成的任务处理文件就在目录下面 如: /xxx/laravel-queue/app/Jobs/DemoQueue.php
5、处理队列的任务类,但是现在我们还没有要处理的队列,那么我们接着使用laravel提供的脚手架生成队列使用的数据库 //查看laravel提供了那些脚手架功能 php artisan //使用php artisan queue:table 生成数据队列驱动的表结构 php artisanqueue:table //执行数据库迁移也就是创建表 php artisan migrate执行完上面的动作之后,如果你前面的数据配置正确,那么你应该和我一样会看到图片上的效果
6、数据表也有,那么模拟几条队列数据到队列里面去,那么就随便创建一个控制来模拟几条数据到队列服务里面去. //生成控制器 php artisan make:controller DemoController //启动一个内部虚拟服务器 php artisan serve //配置web.php的请求路由 Route::get('demo','DemoController@demo'); //新开一个窗口用curl请求 curl -i localhost:8000/demo如果不出意外的话,这个时候jobs表里面就有了三条待处理的消息了
7、消费队列,前面都好理解就是在消费队列的时候,有几个小坑大家要注意,因为在消费队列的时候谁都不能保证服务就一直在如期执行,总会发生点什么意外.有人说可以用try catch捕获,但是不是这样的,即使你在DemoQueue里面捕获,你也拿回去不到异常信息, 跟踪源码发现,是在队列的接口在进行了捕获, 那我们先不考虑错误的情况, 就假如一切都很顺利的执行了 //执行这个命令消费队列 php artisan queue:work --queue=demo
8、但是你担心的事情总会发生的,既然我们知道有些事情会发生那我们就应该提前做好对应的措施,这样你就有更多的时间学习新的东西,刚才我们在DemoQueue里面定义了一个$tries 属性, 队列在处理次数达到这个值的时候还是没有成功的话就会写入到失败的队列表里面去,那现在我们就去模拟一下队列失败的情况. //在生成3条测试队列的数据 curl -i localhost:8000/demo //消费队列 php artisan queue:work --queue=demo这个时候我们看效果, 队列在尝试了三次之后失败了,就把原来的队列给删除了,这个时候如果我们不及时处理的话,就会丢失数据.通过分析错误日志我可以查到一个很重要的信息,那就是我们缺少一个failed_jobs表
9、那问题来了, 我们怎么保存处理失败的队列那, 其实很简单laravel的队列服务提供了补救措施. //生成failed_jobs表 php artisanqueue:failed-table //执行数据库迁移 php artisan migrate
10、这下放心了, 有了保存队列失败的表,我们就不要担心队列丢失的问题了,再次生成模拟数据,进行队列消费 //在生成3条测试队列的数据 curl -i localhost:8000/demo //消费队列 php artisan queue:work --queue=demo这次队列消费还是失败了,但是奇妙的是我们的失败队列被保存到了failed-table表里面去了
11、即然我知品疏饯懒道我们的队列有问题, 那我们就应该去修复这个bug, 或许这个时候你想问有没有一种方法,就是队列处理失败的时候给开发人员发送邮件通知开发人员紧急修复那?对你想的很对,laravel之所以很优雅就是很多设计都很人性化. laravel提供了一个failed方法,laravel的队列会在达到最大重试次数还没有处理成功后就会调用这个方法, 所以你可以可以在这个方法里面写发送邮件的逻辑给开发人员发送告警邮件.这个方法接收一个Exception 类型的参数.那我们去增加这个方法. //在生成3条测试队列的数据 curl -i localhost:8000/demo //消费队列 php artisan queue:work --queue=demo从错误日志里面,我们可以看到failed方法被成功调用了, 所有你可以在这里写发送邮件的逻辑了.
12、对了, 其实在上一步的时候, 我们还是没有把刚才失败的队列给找回来, 好的马上就要写完了, 我们把刚才失败的队列找回来, 接着我把我刚才模拟的错误代码去掉, 然后执行laravel提供的方法找回队列, 找回来的队列会重重新放到jobs表中.是不是我说的这样我们可以试试. //执行如下命令找回处理失败的队列 php artisan help queue:retry后面可以跟failed-table表的id,如果跟id的话, 只会回复对应id值的失败队列到jobs表中, 如果跟all的话全部失败的队列都会重新放回jobs表中
13、最后我们再次执行队列消费的命令就可以消费刚才失败的队列了. //消费队列 php artisan queue:work --queue=demo到这里,我们要说的队列的丬涪斟享正确使用的方法就到这里了, 其中有几个很重要的地方我们要总结一下 1.执行队列的时候一定要加上--tries参数 最好也指定消费的队列名称和连接驱动,如果你不喜欢这样做的话可以写到DemoQueue里面 如:/xxx/php /yyyy/artisan queue:work redis --sleep=3 --tries=3 --queue=zzz 2.除了这种方式laravel还提供一种Queue事件监听的方式来处理失败的队列,这种方式大家可以自行尝试.
14、我们学到了什么? 一 .或许你看完这篇经验,还是一头雾水,那我建议你多看看laravel的手册,总有一头你会恍然大悟,会感慨laravel的设计如此的美妙. 二. 要学会总理解laravel队列的设计思路, 如果我们的业务也有类似的场景,我们完全可以套用这种设计理念, 这也是我这篇经验想表达的核心思想, 因为只有理解了别人造的轮子的优点, 你才可能造出来更好用轮子 三. 大神们请不拍砖,如果这篇经验有帮助到你欢迎关注,欢迎点赞.