laravel6与redis实现消息队列功能

203 阅读3分钟

本人已参与【新人创作礼】活动,一起开启掘金创作之路。

一、说明

本人最近是因为一个项目里面用到了redis消息队列的功能,我这边就写下了记录一下,同时也是为了以后再遇到这类问题的时候,可以更快速,更方便的去实现功能,总之就一句话,一定要细心、细心、再细心,重要的事情说三遍,同时也希望同行的技术伙伴如果有幸被你看到我写的这篇《laravel6与redis实现消息队列功能》的你可以给个关注+点赞+好评,也是支持鼓励我持续创作下去的动力。

二、简介

redis简介

Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。

Redis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务。

三、应用

Laravel 的队列系统

队列配置文件存储在 config/queue.php,在.env文件中,配置queue的连接为 Redis

QUEUE_CONNECTION=redis

任务类

接下来使用命令 php artisan make:job ProcessPlaynum 生成任务类 ,任务类会放在app/Jobs目录下。

序列化与反序列化

把复杂的数据类型压缩到一个字符串中

serialize(): 把变量和它们的值编码成文本形式

unserialize() :恢复原先变量

<?php
 
namespace App\Jobs;
 
use App\Models\Tag;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Redis;
 
 
class ProcessPlaynum implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
    protected $vid;
 
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($vid)
    {
        //
        $this->vid = $vid;
    }
 
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
 
        var_dump($this->vid);
        //取出消息队列里的数据(unserialize反序列化)
        $ceshi = unserialize(Redis::lpop('answers'));
        dump($ceshi );
 
    }
}

handle()方法内执行功能操作。

分发任务

分发任务调用任务类的dispatch方法,dispatch方法中的参数就是你想要传递的数据,将会被传递给任务类的__construct方法。

//在控制器的方法里添加
ProcessPlaynum::dispatch($vid)
//不需要管    
public function __construct($vid)
{
    $this->vid = $vid;
}

同时你还可以使用 onConnection方法指定对应的连接驱动,使用 onQueue指定对应的队列,除此之外,有关于更多使用可以查看Laravel官方文档。

接下来在控制器中编写相关的业务代码:

//控制器里写的方法ce
public function ce(Request $request){
    $vid = $request->input('vid');
    if(empty($vid)){
        return json_encode(['s'=>0,'d'=>'','m'=>'参数异常']);
    }
 
    ProcessPlaynum::dispatch($vid)
        ->onConnection('redis') // 指定连接
        ->onQueue('addPlayNum'); // 指定队列
    return json_encode(['s'=>1,'d'=>'','m'=>'成功']);
}

监听

开启监听队列

php artisan queue:work redis --queue=addPlayNum --tries=3

我们使用 Laravel 队列,会用到 php artisan queue:work 命令,让它监听队列,我们可以通过 nohup 方式让它在后台运行,但是进程如果意外中断是不会自动重启的,所以使用 Supervisor 来监控进程是个很好的方式。

//永久开启进程
nohup php artisan queue:work redis --queue=addPlayNum2 --tries=3
/*
我们使用 Laravel 队列,会用到 php artisan queue:work 命令,让它监听队列,我们可以通过 nohup 方式让它在后台运行,但是进程如果意外中断是不会自动重启的,所以使用 Supervisor 来监控进程是个很好的方式。
*/

supervisor:其实就是用来管理进程的

删除用nohup命令 创建的永久进程,如下图

tries代表失败后最大尝试次数。

上面就是laravel框架与redis消息队列的简单操作

上章中我通过示例代码介绍的挺详细的,要是大家觉得对自己的学习或者工作有参考学习价值,那就给个:关注+点赞+好评。