zwilias / qman
基于事件的beanstalkd队列管理器
Requires
- php: >=5.5.0
- ext-ev: ^0.2
- jeremeamia/superclosure: ^2.1
- psr/log: ^1.0
- zwilias/beanie: ~0.1
Requires (Dev)
- phpunit/php-invoker: ^1.1
- phpunit/phpunit: ^4.7
- scrutinizer/ocular: ^1.1
Suggests
- monolog/monolog: Allows for powerful, granular logging. QMan has full support for psr/log, which this provides.
This package is not auto-updated.
Last update: 2024-09-14 17:42:57 UTC
README
基于事件的beanstalkd队列管理器。
核心功能
- 合理的默认设置,高度可扩展和可配置
- 允许轻松地从连接池中保留
- 支持在接收信号后优雅地关闭
- 保护作业执行免受意外入侵
- 可扩展的作业失败处理
- 内置对PSR-3日志的精细粒度支持
- 内置对队列闭包的支持
要求
用例
QMan针对多个beanstalkd实例以及监听所有这些实例的工作池进行了优化。
示例
队列闭包
队列闭包可能是最简单的事情
use QMan\QMan; $qMan = QMan::create(['localhost:11300']); $qMan->queueClosure(function () { echo 'Hello world!'; });
本质上,这相当于以下内容
use QMan\QMan; use QMan\ClosureCommand; $qMan = QMan::create(['localhost:11300']); $qMan->queue(ClosureCommand::create(function () { echo 'Hello world!'; }));
处理队列
使用默认参数启动工作器很简单
use Beanie\Beanie; use QMan\WorkerBuilder; $beanie = Beanie::pool(['localhost:11300']); $worker = (new WorkerBuilder()) ->build($beanie); $worker->run();
WorkerBuilder
确保使用所有必需的依赖和配置设置 QMan\Worker
队列自定义命令
ClosureCommand
虽然方便,但有两个主要缺点
- 序列化闭包在计算能力上相当昂贵
- 单元测试闭包很快就会变成一大堆混乱
因此,你将经常需要编写自定义命令。
命令应实现 QMan\CommandInterface
,这可以通过扩展 QMan\AbstractCommand
轻松完成
use QMan\AbstractCommand; class CustomCommand extends AbstractCommand { public function getType() { return 'my.custom.command'; } public function execute() { echo $this->getData() * 5; return true; } }
getType()
函数应返回一个字符串,该字符串可以唯一映射到要执行的类。这种间接性是必要的,以便在简单地重启工作器时安全地处理重命名的类等。
为了使QMan工作器能够获取并执行您的命令,您需要确保CommandSerializerInterface
的实例能够识别它。QMan附带了一个名为GenericCommandSerializer
的通用实现。让我们确保我们创建的类已正确注册
use Beanie\Beanie; use QMan\WorkerBuilder; use QMan\GenericCommandSerializer; $serializer = new GenericCommandSerializer(); $serializer->registerCommandType('my.custom.command', CustomCommand::class); $beanie = Beanie::pool(['localhost:11300']); $worker = (new WorkerBuilder()) ->withCommandSerializer($serializer) ->build($beanie); $worker->run();
您可以通过收集类型与类映射,并将类型表示为常量来轻松地为您的应用程序提供未来兼容性
final class Commands { const TYPE_CUSTOM_COMMAND = 'my.custom.command'; public static function $map = [ self::TYPE_CUSTOM_COMMAND => CustomCommand::class ]; }
QMan的GenericCommandSerializer
附带一个registerCommandTypes($map)
函数,可以处理上述情况。
配置
每个Worker
都会接收到一个QManConfig
实例。以下属性目前包含在内
(1):假设您正在使用默认的GenericJobFailureStrategy
。当然,实现用于处理失败作业的自定义策略是完全可能的。
更改配置就像实例化QManConfig
,设置您的配置偏好,并将其传递给CommandBuilder
一样简单
use QMan\QManConfig; use QMan\QManBuilder; use Beanie\Beanie; $config = new QManConfig(); $config->setTerminationSignals([SIGTERM, SIGQUIT]); $beanie = Beanie::pool($servers); $worker = (new WorkerBuilder()) ->withQManConfig($config) ->build($beanie);
处理失败作业
默认情况下,qMan在处理失败作业时将采用一个非常简单的策略
- 失败作业将被埋葬或再次释放
- 如果作业连续失败少于
maxTries
次,它将带(连续失败的次数) * defaultFailureDelay
再次释放 - 否则,当它连续失败
maxTries
次时,它将被埋葬
可以通过实现JobFailureStrategyInterface
(该接口扩展了PSR-3的LoggerAwareInterface
和qMan的ConfigAwareInterface
)轻松覆盖此行为。
use Psr\Log\LoggerAwareTrait; use QMan\JobFailureStrategyInterface; use QMan\Job; use QMan\ConfigAwareTrait; class MyCustomJobFailureStrategy implements JobFailureStrategyInterface { use LoggerAwareTrait, ConfigAwareTrait; public function handleFailedJob(Job $job) { // Do stuff, like deleting the job after 10 total tries $stats = $job->stats(); if ($stats['reserves'] > 10) { $this->logger->alert('Deleting job after failing to successfully execute over 10 times', ['job' => $job]); $job->delete(); } } } use QMan\WorkerBuilder; $worker = (new WorkerBuilder)->withJobFailureStrategy(new MyCustomJobFailureStrategy())->build([...]);
贡献
欢迎提交拉取请求。请确保代码质量(根据scrutinizer)不会太差,并且所有代码都经过彻底的单元测试。
在本地运行测试
$ git clone https://github.com/zwilias/qman.git
$ cd qman
$ composer install
$ vendor/bin/phpunit
许可证
版权所有(c)2015 Ilias Van Peer
在MIT许可证下发布,请参阅所附的LICENSE
文件。