Laravel 5.5 Redis 队列基本使用指南

xiaoxiao2025-08-31  22

仪表盘【不适用于 Windows

仪表盘就是 Horizon 咯

安装

composer require laravel/horizon

配置

发布相关文件(包含配置等)

php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"

参考:Horizon - 配置 |《Laravel 5.5 中文文档》 | PHP / Laravel 社区文档

开始使用

连接/驱动

根据 config/queue.php 文件,我们了解到驱动的配置在项目根目录 .env 文件内

打开 .env 文件,可将 QUEUE_DRIVER 设置为 QUEUE_DRIVER=redis,其下方为 Redis 连接基本配置

# 连接地址 REDIS_HOST=127.0.0.1 # 连接密码 REDIS_PASSWORD= # 连接端口 REDIS_PORT=6379

在 config/database.php 中最下方,我们可以看到 Redis 的默认配置,建议将 database 部分修改为:

'database' => env('REDIS_DB_SELECT', 0)

然后在 .env 文件的 Redis 连接部分下添加一行,Like this。(这样我们可以直接指定其它的 DB)

REDIS_HOST=127.0.0.1 REDIS_PASSWORD= REDIS_PORT=6379 REDIS_DB_SELECT=0

差点忘了,Redis 需要安装依赖

composer require predis/predis

创建任务类

项目根目录执行

php artisan make:job BaseJob

然后在 app\Jobs 目录下得到 BaseJob.php 文件

其中 handle() 方法在队列任务执行触发

添加任务到队列

我们在一个测试用的控制器里面写一个 queue() 方法。

对于测试控制器,路由部分我是这么玩儿的

app\Http\Controllers 下创建 TestController 控制器routes\web.php 内添加Route::any('/test/{action?}', function ($action = '') { return App::make("App\\Http\\Controllers\\TestController")->$action(); }); 这样就可以直接访问 localhost/test/方法名,如果按照我的方法就是这样的:localhost/test/queue

我们继续完善这个方法:

public function queue() { // 可以瞧瞧返回值,记得 use App\Jobs\BaseJob; var_dump(BaseJob::dispatch()); }

切换到 app\Jobs\BaseJob.php 文件,在 handle() 方法里面添加一点输出内容:

public function handle() { echo "job executed\n"; $this->delete(); }

至此一个简单的队列就完成了,接下来让我们运行它。

发布任务、执行任务

我们直接请求 http://localhost/test/queue【地址自己替换一下】,将任务发布到 Redis 里面,页面上返回结果如下:

object(Illuminate\Foundation\Bus\PendingDispatch)[467] protected 'job' => object(App\Jobs\BaseJob)[463] public 'tries' => int 3 public 'timeout' => int 60 private 'type' => null private 'data' => array (size=0) empty protected 'job' => null public 'connection' => null public 'queue' => null public 'chainConnection' => null public 'chainQueue' => null public 'delay' => null public 'chained' => array (size=0) empty

需要了解的是,这个任务我们并没有指定队列名称,所以它使用的是默认队列名称 default,我们通过一些 Redis GUI 软件可以看到任务详情。

当然这不重要,Redis 里面的数据表示任务已经添加到队列中了,接下来只需要执行这个任务就行。在项目根目录戳如下命令:

# --once 表示执行一次,如果不添加 --once 参数,该命令会持续监听队列。如需终止,请按 Ctrl+C/control+C php artisan queue:work --once

命令行会返回如下内容:

[2018-10-25 18:18:32] Processing: App\Jobs\BaseJob job executed [2018-10-25 18:18:32] Processed: App\Jobs\BaseJob

至此一个简单的队列任务添加、发布、执行就完成了。

更多使用姿势

传递自定义数据

我们将 queue() 方法改成如下内容:

var_dump(BaseJob::dispatch(['name' => 'Max Sky', 'gender' => 1]) ->onQueue('MyQueue'));

此处我们在 dispatch 方法内放入了一个数组,该数组在任务执行时可得到并使用;onQueue 方法指定了一个队列名称。

回到 BaseJob.php,调整构造函数如下:

private $data; public function __construct($data = []) { $this->data = $data; }

修改 handle() 方法如下:

public function handle() { print_r($this->data); $this->delete(); }

好了,让我们刷新一下网页 http://localhost/test/queue

结果已经有了变化:

object(Illuminate\Foundation\Bus\PendingDispatch)[467] protected 'job' => object(App\Jobs\BaseJob)[463] public 'tries' => int 3 public 'timeout' => int 60 private 'type' => null private 'data' => array (size=2) 'name' => string 'Max Sky' (length=7) 'gender' => int 1 protected 'job' => null public 'connection' => null public 'queue' => string 'MyQueue' (length=7) public 'chainConnection' => null public 'chainQueue' => null public 'delay' => null public 'chained' => array (size=0) empty

队列名称和自定义数据都显示出来了。

Redis 中有了新的队列名称 Key

Value 部分看起来是这样的:

{ "displayName": "App\\Jobs\\BaseJob", "job": "Illuminate\\Queue\\CallQueuedHandler@call", "maxTries": 3, "timeout": 60, "timeoutAt": null, "data": { "commandName": "App\\Jobs\\BaseJob", "command": "O:17:\"App\\Jobs\\BaseJob\":11:{s:5:\"tries\";i:3;s:7:\"timeout\";i:60;s:23:\"\u0000App\\Jobs\\BaseJob\u0000type\";N;s:23:\"\u0000App\\Jobs\\BaseJob\u0000data\";a:2:{s:4:\"name\";s:7:\"Max Sky\";s:6:\"gender\";i:1;}s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";s:7:\"MyQueue\";s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";N;s:7:\"chained\";a:0:{}}" }, "id": "1", "attempts": 0, "type": "job", "tags": [], "pushedAt": 1540464437.013529 }

然后我们再试试执行这个任务:

php artisan queue:work --once

咦?什么都没有发生。。。因为我们指定了队列名称,所以在执行的时候也必需指定:

php artisan queue:work --once --queue=MyQueue

返回结果如下,可以发现自定义的数据被传递进来:

[2018-10-25 18:53:08] Processing: App\Jobs\BaseJob Array ( [name] => Max Sky [gender] => 1 ) [2018-10-25 18:53:08] Processed: App\Jobs\BaseJob

延时任务

在某些情况下我们需要延时执行一些任务,delay 方法可以很好的协助我们完成这个操作。

这次我们先执行任务监听命令,去掉 --once 参数:

php artisan queue:work --queue=MyQueue

然后修改 queue 方法如下:

public function queue() { var_dump(BaseJob::dispatch(['name' => 'Max Sky', 'gender' => 1]) ->onQueue('MyQueue') // 此处使用了 Laravel 内置的 Carbon 库,Carbon 是一个优秀的时间工具类 // Carbon::now() 表示获取当前时间;addSecond 表示在当前时间上增加 10 秒 // 意思就是延时 10s 后执行任务 ->delay(Carbon::now()->addSecond(10))); }

接着刷新网页,结果如下:

object(Illuminate\Foundation\Bus\PendingDispatch)[467] protected 'job' => object(App\Jobs\BaseJob)[463] public 'tries' => int 3 public 'timeout' => int 60 private 'type' => null private 'data' => array (size=2) 'name' => string 'Max Sky' (length=7) 'gender' => int 1 protected 'job' => null public 'connection' => null public 'queue' => string 'MyQueue' (length=7) public 'chainConnection' => null public 'chainQueue' => null public 'delay' => object(Carbon\Carbon)[469] public 'date' => string '2018-10-25 19:05:32.647479' (length=26) public 'timezone_type' => int 3 public 'timezone' => string 'PRC' (length=3) public 'chained' => array (size=0) empty

赶紧回到命令行,等待 10s 后命令行有了结果【小误差请忽略。。。】:

[2018-10-25 19:05:34] Processing: App\Jobs\BaseJob Array ( [name] => Max Sky [gender] => 1 ) [2018-10-25 19:05:34] Processed: App\Jobs\BaseJob

使用仪表盘

如果已安装 laravel/horizon 并发布了配置文件,我们可以利用仪表盘来管理任务。

编辑 config/horizon.php,在最下方的 environments 中,将 production 和 local 内的 queue 分别加上我们的自定义队列名称。

结果如下:

'environments' => [ 'production' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default', 'MyQueue'], // 此处添加队列名称 'balance' => 'auto', 'processes' => 10, 'tries' => 3, ], ], 'local' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default', 'MyQueue'], // 此处添加队列名称 'balance' => 'auto', 'processes' => 3, 'tries' => 3, ], ], ],

然后我们直接执行如下命令就可以监听队列任务,并通过仪表盘页面查看任务信息了: 【执行如下命令后,可替代之前的队列命令,意味着无需再执行 php artisan queue:work --MyQueue】

php artisan horizon

成功后命令行返回 Horizon started successfully.

最后我们访问 http://localhost/horizon 就进入了仪表盘页面。

左边可以查看最近的任务、失败的任务等相关信息。

仪表盘默认只能在本地环境中使用,如需在发布环境中使用需配置自定义授权规则:Horizon - 仪表盘权限验证 |《Laravel 5.5 中文文档》 | PHP / Laravel 社区文档

更多

本文章对 Laravel 5.5 中的队列使用做了比较简单的描述,更多信息包括优先级、Supervisor 使用、失败任务处理、重试次数等参考文档翻译:队列 | 《Laravel 5.5 中文文档》 | PHP / Laravel 社区文档

至天 认证博客专家 Max Sky PHPer ------------------------------------------------------------
转载请注明原文地址: https://www.6miu.com/read-5035500.html

最新回复(0)