urbanindo/yii2-queue

Yii2 的队列组件

3.0.0 2018-12-18 18:10 UTC

README

此组件为 Yii2 提供队列组件。

Latest Stable Version Total Downloads Latest Unstable Version Build Status codecov

需求

要运行监听器,您需要启用 PCNT 扩展

安装

安装此扩展的首选方式是通过 composer

运行

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

或者在您的 composer.json 文件的 require 部分添加以下内容:

"urbanindo/yii2-queue": "*"

```json

```

设置

安装后,第一步是设置控制台控制器。

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

对于任务工作者,设置一个新的模块,例如 task 并在配置中声明它。

'modules' => [
    'task' => [
        'class' => 'app\modules\task\Module',
    ]
]

然后设置队列组件。不要忘记在组件中设置运行任务的模块名称。例如,使用 AWS SQS 的队列

'components' => [
    'queue' => [
        'class' => 'UrbanIndo\Yii2\Queue\Queues\SqsQueue',
            'module' => 'task',
            'url' => 'https://sqs.ap-southeast-1.amazonaws.com/123456789012/queue',
            'config' => [
                'credentials' => [
                    'key' => 'AKIA1234567890123456',
                    'secret' => '1234567890123456789012345678901234567890'
                ],
                'region' => 'ap-southeast-1',
                'version' => 'latest'
            ]
        ]
    ]
]

或使用数据库队列

'components' => [
    'db' => [
        // the db component
    ],
    'queue' => [
        'class' => 'UrbanIndo\Yii2\Queue\Queues\DbQueue',
        'db' => 'db',
        'tableName' => 'queue',
        'module' => 'task',
        // sleep for 10 seconds if there's no item in the queue (to save CPU)
        'waitSecondsIfNoQueue' => 10,
    ]
]

使用方法

创建工作者

创建工作者与创建控制台或网络控制器相同。在任务模块中创建一个控制器,该控制器扩展 UrbanIndo\Yii2\Queue\Worker\Controller

例如:

class FooController extends UrbanIndo\Yii2\Queue\Worker\Controller
{
    public function actionBar($param1, $param2)
    {
        echo $param1;
    }
}

为了防止作业从队列中删除(例如,当作业未完成时),在操作中返回 false。作业将在下次机会再次运行。

例如:

class FooController extends UrbanIndo\Yii2\Queue\Worker\Controller
{
    public function actionBar($param1, $param2)
    {
        try {
            // do some stuff
        } catch (\Exception $ex) {
            \Yii::error('Ouch something just happened');
            return false;
        }
    }
}

运行监听器

要运行监听器,运行上面配置中设置的命令行。如果控制器映射为 queue,则运行。

yii queue/listen

发布作业

要从源代码发布作业,请放置如下内容。

use UrbanIndo\Yii2\Queue\Job;

$route = 'foo/bar';
$data = ['param1' => 'foo', 'param2' => 'bar'];
Yii::$app->queue->post(new Job(['route' => $route, 'data' => $data]));

作业也可以从控制台发布。第二个参数中的数据是 JSON 字符串。

yii queue/post 'foo/bar' '{"param1": "foo", "param2": "bar"}'

作业也可以作为匿名函数发布。请注意使用此功能。

Yii::$app->queue->post(new Job(function() {
    echo 'Hello World!';
}));

延迟事件

在此队列中,有一个名为 延迟事件 的功能。基本上,使用此功能,我们可以使用队列延迟执行在某个事件之后执行的过程。

要使用此功能,请在组件中添加行为并实现定义的事件处理程序。

    public function behaviors()
    {
        return [
            [
                'class' => \UrbanIndo\Yii2\Queue\Behaviors\DeferredEventBehavior::class,
                'events' => [
                    self::EVENT_AFTER_VALIDATE => 'deferAfterValidate',
                ]
            ]
        ];
    }

    public function deferAfterValidate()
    {
        // do something here
    }

注意 由于减少消息大小,通常在触发事件时传递的 $event 对象将不会传递给延迟事件。此外,调用方法的对象只是一个克隆对象,因此它不会具有原始对象中附加的行为和事件。

对于 ActiveRecord 类,由于 PDO 序列化的 SuperClosure 限制,无法传递对象,因此应该使用 \UrbanIndo\Yii2\Queue\Behaviors\ActiveRecordDeferredEventBehavior。区别在于延迟事件处理程序调用的对象。

由于我们不能传递原始对象,调用对象将使用主键从表中重新检索。对于 afterDelete 事件,由于相应的行不再表中,调用对象是一个新对象,其属性是从原始对象的属性分配的。

Web 端点

我们可以通过将 \UrbanIndo\Yii2\Queue\Web\Controller 添加到控制器映射来使用队列。

例如:

'controllerMap' => [
    'queue' => [
        /* @var $queue UrbanIndo\Yii2\Queue\Web\Controller */
        'class' => 'UrbanIndo\Yii2\Queue\Web\Controller'
    ]
],

要发布此内容,请使用以下方法:

curl -XPOST http://example.com/queue/post --data route='test/test' --data data='{"data":"data"}'

要限制对控制器的访问,我们可以使用 \yii\filters\AccessControl 过滤器。

例如,要按 IP 地址进行过滤,我们可以使用以下方法:

'controllerMap' => [
    'queue' => [
        /* @var $queue UrbanIndo\Yii2\Queue\Web\Controller */
        'class' => 'UrbanIndo\Yii2\Queue\Web\Controller',
        'as access' => [
            'class' => '\yii\filters\AccessControl',
            'rules' => [
                [
                    'allow' => true,
                    'ips' => [
                        '127.0.0.1'
                    ]
                ]
            ]
        ]
    ]
],

测试

要运行测试,在根目录中执行以下操作。

./vendor/bin/phpunit

路线图

  • 添加更多队列提供者,例如MemCache、IronMQ、RabbitMQ。