Laravel进阶系列笔记--(八)Laravel 基于Reids的消息队列的使用

作者: 温新

分类: 【Laravel】

阅读: 2601

时间: 2021-08-17 13:21:50

作者:温新

时间:2021-07-09

hi,我是温新,一名PHPer。

本篇文章紧接着 Laravel进阶系列笔记--(7)Laravel 基础数据库存储的消息队列的使用 篇文章,两篇文章之前的关系是紧密相连,同时,本篇 Redis消息队列的使用 是基于该篇的操作进行的。

基于Redis的队列任务

第一步:windows下安装Redis数据库与Redis扩展

关于Redis的安装请自行安装。

第二步:修改驱动为Redis

文件:.env

// 修改redis驱动
QUEUE_CONNECTION=redis

只要把驱动修改为redis,其他的什么都不要动。没错,就是这样的简单,这样的优雅。

修改为Redis驱动,windows中打开Redis服务器与客户端。

第三步:创建任务类

php artisan make:job SendEamilToUser

该命令会在app/Jobs目录下生成SendEamilToUser.php文件。

编辑SendEamilToUser.php文件进行消息队列任务的处理

<?php
namespace App\Jobs;

use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class SendEamilToUser implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public $user = null;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        // 此处执行自定义任务
        Log::info('发送邮件给 【' . $this->user->name . '】 用户成功' );
    }
}

第四步:派发任务给队列

1)定义路由

// web.php

Route::get('queue', 'UserController@queue');

2)添加queue方法并编写任务代码

// UserController.php

use App\Jobs\SendEamilToUser;

public function queue()
{
    $users = \App\Models\User::all();
    foreach ($users as $user) {
        // 为每个用户发送消息的任务
        // 方式一
        //dispatch(new SendEamilToUser($user));
		  // 方式二
        SendEamilToUser::dispatch($user);
    }
    return '派发队列任务成功';
}

打开jobs数据表就会看到相关的任务信息了。

3)访问路由添加队列任务

// 添加队列任务完成后,通过redis客户端进行查看。
127.0.0.1:6379> keys *
1) "laravel_database_queues:default:notify"
2) "laravel_database_queues:default"
127.0.0.1:6379> type laravel_database_queues:default:notify
list

第五步:执行队列任务

// 执行所有任务
php artisan queue:work

第六步:查询日志文件

[2021-07-09 13:35:43] local.INFO: 发送邮件给 【Dell Terry】 用户成功  
[2021-07-09 13:35:43] local.INFO: 发送邮件给 【Thomas Bruen】 用户成功  

如此,任务完成。

有没有注意到一个问题,要查看队列任务很不方便,与数据库相比,可观性太差了。好在,Laravel官方提供了Horizon扩展包解决了此问题。

可视化的Horizon队列系统解决方案

使用Horizon

第一步:安装Horizon

composer require laravel/horizon

报错: Install or enable PHP's pcntl extension.的解决方法

由于是在windows中,可能会报相关扩展的错误,错误如下:

- laravel/horizon[v5.7.0, ..., 5.x-dev] require ext-pcntl * -> it is missing from your system. Install or enable PHP's pcntl extension.
    - Root composer.json requires laravel/horizon ^5.7 -> satisfiable by laravel/horizon[v5.7.0, ..., 5.x-dev].

解决方法如下:

1)打开composer.json文件,添加如下配置

"config": {
    "optimize-autoloader": true,
    "preferred-install": "dist",
    "sort-packages": true,
    "platform": {
        "ext-pcntl": "7.2",
        "ext-posix": "7.2"
    }
},

2)安装

composer install

3)重新安装Horizon

第二步:发布资源并生成配置配置文件

php artisan horizon:install

config目录下生成horizon.php配置文件

第三步:访问后台

可以通过horizon路由对队列后台进行访问。

8-1-horizon

可以看到状态是Inactive未启动的状态,下面开始启动

第四步:运行Horizon

php artisan horizon

使用 php artisan horizon 报错:Call to undefined function Laravel\Horizon\Console\pcntl_async_signals()

很遗憾,pcntl扩展安装失败,虽然第一步的报错解决,显示也是安装成功,但是确实没有安装上。windows对此支持很是不友好,第四步无法执行成功。

windows下我没有找到解决方法,因此使用终端进行监控。

// 终端监控
php artisan queue:listen

到此使用horizon完毕

Horizon其他命令

暂停horizon

php artisan horizon:pause

继续horizon

php artisan horizon:continue

查看horizon状态

php artisan horizon:status

优雅的终止horizon

php artisan horizon:terminate

该命令会在所有当前正在执行的任务执行完成后退出horizon.

关于horizon还有一些其他的使用,请参考官方访访文档。

消息队列篇--完。

我是温新

每天进步一点点,就一点点

请登录后再评论