队列与定时任务
2026/10/26大约 1 分钟
队列与定时任务
异步与到点执行两类基础设施,插件侧统一经 QueueService、TaskRegistry 接入。
Redis 队列
基座用 webman/redis-queue。内置消费者在 app/queue/redis/:
| Job | 队列 / 用途 |
|---|---|
SendNotifyJob | send_notify,异步发通知 |
PluginJobConsumer | plugin_job,插件统一信封队列的消费者 |
LicenseHeartbeatJob | 授权心跳 |
约定(见后端规范·队列):消费者实现 Consumer、任务幂等、捕获异常、记日志;投递 Client::send($queue, $data, $delay)。
插件侧不直接建消费者类,而是走信封队列 QueueService:
QueueService::dispatch('{name}_{action}', $payload, $delay, $dedupKey); // 投 plugin_job,返 bool
QueueService::consume('{name}_{action}', fn(array $p) => ..., $owner); // boot() 内注册处理队列不可用时 dispatch 记日志返 false,调用方按返回值降级。QueueService::consume 的 jobHandler 必须幂等(会重试)。详见队列·任务·推送。
定时任务
workerman/crontab 驱动。专用进程 app/process/PluginTask.php(count=1)在 onWorkerStart 把 TaskRegistry 里的任务登记到 crontab,任务体加 Redis 锁防多实例重复执行。
插件注册定时任务:
TaskRegistry::schedule('{name}_{action}', '* * * * *', fn() => ..., $owner); // cron 5 段,job 无参且幂等特性开关
队列受 queue_enabled(默认 true)、任务受 task_enabled(默认 true)控制,见 config/plugin_extend.php。开关关闭时对应注册被忽略。改开关要重启。
Redis 锁的参数形式
PluginTask、PluginJobConsumer、SendNotifyJob 里设置过期锁要用 illuminate/redis 位置参数 Redis::set($k,$v,'EX',$ttl,'NX'),用 phpredis 数组选项会 TypeError。见缓存规范。
