Serve 基于Swoole Server 编写的消息队列消费系统
已支持功能:
支持数据库操作
仅支持Redis 作为消息队列
允许开启多个 Worker+TaskWorker+Master模式 监控不同队列
环境要求:
PHP >= 7.2
ext-Swoole
ext-SeasLog (暂时未实现日志,无需安装扩展:后期添加)
运行如图:
调试模式 "php bin/email_delay.php start --queue delayer::email_queue"
守护进程模式 "php bin/email_delay.php start --queue delayer::email_queue"
Serve-Queue 是什么?
通过Swoole Server 实现消费端并命名为 “Serve-Queue”,Swoole Server API 都可以轻松实现; 支持多进程独立监控每个消息队列数据,主要应用于耗时场景:超时订单自动关闭、自动评论、发送邮件 .... 等等。
核心特点
命令行:快速实现消息中间件消费、支持守护进程、常驻内存;
自动加载:基于 PSR-4 ,完全使用 Composer 构建;
模块化:支持 Composer ,可以很方便的使用第三方库;
Install
$> git clone https://github.com/twomiao/Serve.git
$> cd Serve/
$> composer install
Run
$> php bin/order_delay.php start --queue delayer::order_queue # debug mode 订单自动关闭队列
$> php bin/order_delay.php start -d --queue delayer::order_queue # daemonize mode
$> php bin/email_delay.php start -d --queue delayer::email_delay # daemonize mode 邮件发送队列
$> ...... .... 以及更多多进程独立监控不同队列
命令结构
例子:php bin/order_delay.php start --queue delayer::order_queue
start: php bin/order_delay.php start --queue 被监控队列名称 # 警告:队列名称不允许重复
例子:php bin/order_delay.php stop xxx.pid # 警告: cat ../bin/pid/email_delay.php.pid里面的进程号
stop xxx_pid: php bin/order_delay.php stop xxx_pid # stop 不允许重复
支持命令
start: 调试模式运行;
start -d or d: 守护进程运行 [ 自动关闭输入输出信息 ];
stop pid: 停止某一个Serve-Queue;
Job Code
require_once dirname(__DIR__) . '/vendor/autoload.php';
date_default_timezone_set('Asia/Shanghai');
use Serve\Processor\Command as OrderCommand;
// 处理订单队列命令,需要监控多个队列请在bin/xxx.php 添加更多相似命令
$orderProcessor = new OrderCommand($argv);
// 1.1 执行正常业务逻辑
$orderProcessor->handle(function ($serve, $data) {
/**
* 正常业务执行
* 1.1 $serve->pdo 操作数据库的客户端句柄
* 1.2 $serve->redis 操作句柄
* 1.3 $data 队列中的数据
*/
// throw new Exception('by zero!');
// var_dump(get_class($serve->pdo));
// var_dump(json_encode($data));
// print ($serve->redis->)
return 'success';
})
// 2.1 正常业务逻辑返回结果, 比如"success"
// 2.2 注意:then(function{}); 可选方法,业务不需要不填写就行了
->then(function ($serve, $data) {
/**
* 处理handle() return的结果
*/
var_dump($data);
})
// 3.1 service.job_wait 任务完成,如果超时执行
// 3.2 注意:catch(function{}); 可选方法,业务不需要不填写就行了
->catch(function ($serve, $data) {
/***
* 任务超时执行
*/
print('job exec timeout' . PHP_EOL);
})
// 4.1 执行handle(function(){}) 出现异常代码在这里处理即可
// 4.2 注意:fails(function{}); 可选方法,业务不需要不填写就行了
->fails(function ($data, $retry) {
/***
* 出现异常也就是任务出现失败情况执行
*/
if ($retry > 0) {
// 说明此任务已经失败重试超过了,配置文件设置最大值
}
var_dump($data);
var_dump($retry);
})
->exec();