Yii2 queue队列使用

场景

发送邮件是一个典型的应用场景,我们无法忍受等待漫长的时间来发送一封邮件,可以将其放入队列,不影响当前程序的执行,后台监听队列里的任务即可。

组件

yii2 + redis + yii2-queue

安装

设置redis

注:redis不限于queue使用,yii2-queue不限于redis驱动

单独将redis配置拉出来,可以web、console公用,配置新增redis.php

return [
    'class' => 'yii\redis\Connection',
    'hostname' => 'localhost',
    'port' => 6379,
    'database' => 0,
];

console和web中引入redis组件

'redis' => require (__DIR__ . '/redis.php'),

设置queue

安装

源码:https://github.com/urbanindo/yii2-queue

php composer.phar require --prefer-dist urbanindo/yii2-queue "*"

配置模块

所有的worker(progress)都写在这里。

创建模块’app\modules\queue\Queue’:

namespace app\modules\queue;

use yii\base\Module;

class Queue extends Module {

    public function init()
    {
        parent::init();
    }

}

并在console的配置文件中声明模块:

'modules' => [
    'queue' => [
        'class' => 'app\modules\queue\Queue',
    ],
],

配置命令行

设置console的配置文件:

'controllerMap' => [
 // ...
    'queue' => [
        'class' => 'UrbanIndo\Yii2\Queue\Console\Controller',
        //'sleepTimeout' => 1
    ],
],

设置好后可以使用命令:

- queue                           QueueController handles console command for running the queue.
    queue/listen                  This will continuously run new subprocesses to fetch job from the queue.
    queue/peek                    Peek messages from queue that are still active.
    queue/post                    Post a job to the queue.
    queue/purge                   Purging messages from queue that are still active.
    queue/run                     Fetch a job from the queue.
    queue/run-task                Run a task without going to queue.
    queue/test                    @return void

配置队列驱动

可以参考源文件tests/Queues目录中的测试文件,https://github.com/urbanindo/yii2-queue/tree/master/tests/Queues

比如使用redis驱动

新增配置文件queue.php

return [
    'class' => '\UrbanIndo\Yii2\Queue\Queues\RedisQueue',
    'module' => 'queue',
    'key' => 'analytics:queue',
];

console及web中引入queue组件

'queue' => require (__DIR__ . '/queue.php'),

使用

worker

耗费时间的代码进程都写在这里

namespace app\modules\queue\controllers;

use UrbanIndo\Yii2\Queue\Worker\Controller;

class AccessController extends Controller {

    public function actionTest($param = 'test') {
        sleep(10);
        echo $param;
    }
}

dispatch

提交一个任务

$route = 'access/test';
$data = [
    'param' => 'wjoadm'
];
$job = new Job([
    'route' => $route,
    'data' => $data
]);
\Yii::$app->queue->post($job);

listen

监听任务

php yii queue/listen
php yii queue/run

 

注意

如果提交任务的时候报错:

Only variables should be passed by reference

请确保

\Yii::$app->queue->post($job);

$job一定是以变量形式传入,因为post()中的$job是一个引用