1、配置队列:composer require "predis/predis:~1.0"
2、在ENV中配置:QUEUE_DRIVER=redis
3、配置表,失败时队列的失败信息内容会存到此表里。命令:php artisan queue:failed-table
4、生成记录失败的数据表:php aritsan migrate
5、生成一个任务类出来:php artisan make:job Wpl 会在app目录下会生成Jobs/Wpl.php
6、打开Wpl.php在handle方法写如下代码:
<?php
namespace 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 Wpl implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//测试
file_put_contents('wpl.txt','laravel队列的测试');
echo '恭喜执行成功';
}
}
7、启动队列监听,第一种方式: php artisan queue:listen 第二种方式: 根目录执行 php artisan queue:work
8、控制器调用队列,随便找一个可以访问的控制器方法,复制下面代码:
\App\Jobs\Wpl::dispatch()->delay(10);
echo 'laravel队列测试';die;
9、访问控制对应的路由结果如图:同时会在项目的根目录生成一个wpl.txt文件
队列可能遇到的问题:
1、laravel修改retry_after/expire解决队列任务过期/超时导致队列多次执行问题
在生产环境中,我发现当客户上传几万数据时,处理时间一般比较长(由于数据结构大,大约几分钟);我发现Laravel
队列不报错但是执行了3次(我的异常尝试次数最多为3次),但是系统并未报错,我开始排查队列不报错但是多次执行的原因,发现存在队列过期的问题,修改retry_after
解决问题。如果你是laravel 5.3
以下环境,修改expire
即可(Redis队列)。
2、任务过期
config/queue.php
配置文件里,每一个队列连接都定义了一个retry_after
选项。这个选项指定了任务最多处理多少秒后就被当做失败重试了。比如说,如果这个选项设置为90
,那么当这个任务持续执行了90
秒而没有被删除,那么它将被释放回队列。通常情况下,你应该把 retry_after 设置为最长耗时的任务所对应的时间。
唯一没有
retry_after
选项的连接是Amazon SQS
。当用Amazon SQS
时,你必须通过Amazon
命令行来配置这个重试阈值。
3、队列处理器超时
queue:work
Artisan
命令对外有一个--timeout
选项。这个选项指定了Laravel
队列处理器最多执行多长时间后就应该被关闭掉。有时候一个队列的子进程会因为很多原因僵死,比如一个外部的HTTP
请求没有响应。这个--timeout
选项会移除超出指定事件限制的僵死进程:
php artisan queue:work --timeout=60
retry_after
配置选项和--timeout
命令行选项是不一样的,但是可以同时工作来保证任务不会丢失并且不会重复执行。
--timeout
应该永远都要比retry_after
短至少几秒钟的时间。这样就能保证任务进程总能在失败重试前就被杀死了。如果你的--timeout
选项大于retry_after
配置选项,你的任务可能被执行两次。
在命令行中运行Artisan命令执行队列中的任务。Laravel为此提供了三种Artisan命令: queue:work 默认只执行一次队列请求, 当请求执行完成后就终止; queue:listen 监听队列请求,只要运行着,就能一直接受请求,除非手动终止; queue:work --daemon 同 listen 一样, 只要运行着,就能一直接受请求,不一样的地方是在这个运行模式下,当新的请求到来的时候,不重新加载整个框架,而是直接 fire 动作。能看出来, queue:work --daemon是最高级的,一般推荐使用这个来处理队列监听。 注:使用 queue:work --daemon ,当更新代码的时候,需要停止,然后重新启动,这样才能把修改的代码应用上。 所以我们接下来在命令行中运行如下命令: php artisan queue:work --daemon