urbanindo / yii2-queue
Yii2 的队列组件
Requires
- php: ^7.2
- ext-pcntl: *
- aws/aws-sdk-php: >=2.4
- jeremeamia/superclosure: >=2.0
- symfony/process: >=2.4
- yiisoft/yii2: >=2.0.15
Requires (Dev)
- flow/jsonpath: dev-master
- fzaninotto/faker: dev-master
- phpunit/dbunit: ^3.0
- phpunit/php-code-coverage: ^5.2
- phpunit/phpunit: ^6.5
- squizlabs/php_codesniffer: ^3.3
- videlalvaro/php-amqplib: 2.5.*
- yiisoft/yii2-coding-standards: *
- yiisoft/yii2-redis: *
This package is auto-updated.
Last update: 2024-09-22 16:13:20 UTC
README
此组件为 Yii2 提供队列组件。
需求
要运行监听器,您需要启用 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。