laravel队列的使用

本文介绍了如何在Laravel中使用队列处理延时任务和高并发操作。通过配置QUEUE_CONNECTION选择数据库驱动,创建任务类,调度任务并使用队列监听器运行。队列驱动包括sync、database、beanstalkd、sqs和redis。队列的运行方式包括queue:listen和queue:work --daemon,推荐使用queue:work --daemon以保持守护进程运行。在部署时,需要注意线上环境的.env配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在开发的过程中,遇到了这样一个场景:用户评论完之后需要延时一段时间来给代表推送企业微信消息,要求延时时间可以后台配置。这个时候我们首先就考虑到用队列实现。

队列之前也是经常使用,当时laravel的队列倒是第一次尝试,花了一个小时看英文文档,然后就可以按部就班的实现一个小的队列任务了。

laravel Queue

原理:它就类似写一个死循环的脚本在Linux系统持续运行,新的队列任务不断push到这个脚本中。所谓队列,会有数据的生产者和消费者之分。生产者向队列中投递数据,消费者从队列中获取数据。

使用场景:一种是高并发的情况,一种是耗时的操作,可以将任务放到队列中去,消费者从队列取任务执行,当然还有失败的情况如何处理,以及延迟,重试,更复杂的情况还有优先级的实现。

系统配置:laravel queue可配置多种队列驱动,包括 "sync", "database", "beanstalkd", "sqs", "redis", "null"(具体参见app/config/queue.php)
其中sync为同步,database为使用数据库,后面三种为第三方队列服务,最后一种为不使用队列。
通过在 .env 中的 QUEUE_CONNECTION 选项,来决定选择何种驱动。
如 QUEUE_CONNECTION=database 即为选择数据库驱动队列。

使用数据库驱动队列

(1)生成任务表

在终端下输入

php artisan queue:table
php artisan migrate

在数据库连接正常的情况下,会在数据库中出现jobs表:

  [id] bigint  
  [queue] nvarchar(255) 
  [payload] nvarchar(max) 
  [attempts] tinyint 
  [reserved_at] int  
  [available_at] int  
  [created_at] int  

(2) 创建任务类

php artisan make:job sendToRepMessage

在终端内执行上述命令,会自动生成 app/Jobs/sendToRepMessage.php 文件

class sendToRepMessage implements ShouldQueue{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    private $data;
    /**
     * 任务最大尝试次数。
     *
     * @var int
     */
    public $tries = 3;
    /**
     * 任务运行的超时时间。
     *
     * @var int
     */
    public $timeout = 180;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        //
        $this->data=$data;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //逻辑代码
    }
}

在该文件的handle方法中,可以放置任务处理逻辑。

(3) 发送任务

在任意位置,均可像下面一样调用 dispatch 发送任务

SendMail::dispatch($email);

对于队列中很常用的一个场景,延迟任务,我们只需调用delay()方法

ProcessPodcast::dispatch($podcast)->delay(now()->addMinutes(10))   //延时10分钟

完成上述步骤后,可以在数据库中发现一条记录(导出为insert SQL语句):

INSERT INTO [jobs]([id], [queue], [payload], [attempts], [reserved_at], [available_at], [created_at]) VALUES (6, N'default', N'{"displayName":"App\\Jobs\\sendToRepMessage","job":"Illuminate\\Queue\\CallQueuedHandler@call","maxTries":null,"timeout":null,"timeoutAt":null,"data":{"commandName":"App\\Jobs\\sendToRepMessage","command":"O:23:\"App\\Jobs\\sendToRepMessage\":8:{s:29:\"\u0000App\\Jobs\\sendToRepMessage\u0000data\";s:6:\"111222\";s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";N;s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";N;s:7:\"chained\";a:0:{}}"}}', 0, NULL, 1545980176, 1545980176);

此时任务已经放置在数据库内,只有将队列运行起来后,队列才能主动调用回调方法。

(4)运行队列监听器 

// 运行队列监听器(执行队列)
php artisan queue:listen

//在linux中,如果想让它在后台执行,可以这样:
 php artisan queue:listen &

如果修改了队列的代码,我们需要重启队列。

//重启队列
php artisan queue:restart

(5)失败队列

//生成失败迁移表
php artisan queue:failed-table
php artisan migrate
//查看失败任务
php artisan queue:failed
//执行某个失败任务
// retry id
php artisan queue:retry id
//全部 all
php artisan queue:all
//删除某个任务
//forget id
php artisan queue:forget id
//删除所有任务
php artisan queue:flush

 (6)守护进程

为了保证应用服务的稳定性,需要开启守护进程。
Linux下,一般使用 Supervisor ,Windows下使用 Forever.

我们再来说一下queue:listen 和 queue:work --daemon 的区别

  • queue:work 默认只执行一次队列请求, 当请求执行完成后就终止;
  • queue:listen 监听队列请求, 只要运行着, 就能一直接受请求, 除非手动终止;
  • queue:work --daemon 同 listen 一样, 只要运行着, 就能一直接受请求, 不一样的地方是在这个运行模式下, 当新的请求到来的时候, 不重新加载整个框架, 而是直接 fire 动作.

能看出来, queue:work --daemon 是最高级的,也是在 Laravel 4.2 以后才加入的,一般推荐使用这个来处理队列监听.

注意: 使用 queue:work --daemon , 当更新代码的时候, 需要停止, 然后重新启动, 这样才能把修改的代码应用上.

配置完成后,本地的环境是搭建好了。问题是如果push到线上,则需要特别注意的是,更改线上的.env文件,否则就不会生效。

整体来说,看英文文档还是非常有必要的,英文原版的一些内容在中文翻译版中可能直接减掉了,虽然不是一些主要功能,但是对于开发流畅性还是有一定影响的。再就是原版英文文档的描述更清晰一些,尤其是某些定义、参数的设置,在中文翻译中可能就被省略掉了,这会在开发中埋下雷,早晚会踩。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值