在hyperf 3.1中需启用注解扫描并配置async_queue.php的processes>0,使用@asyncqueuemessage注解方法,调用时由aop拦截自动投递至redis队列,消费者进程反序列化后反射执行。

要在 Hyperf 3.1 中用注解方式快速投递异步任务,避免手动 new Job → push 的冗余流程,必须让框架自动识别方法并封装为队列任务,同时确保消费进程能正确加载和执行。
启用注解支持并确认基础配置
先检查项目是否已启用 Hyperf 的注解扫描机制:打开 config/autoload/annotations.php,确认 'scan' => ['paths' => [...]] 包含你的 app/ 或 app/Service 目录;若缺失,需手动补全,否则 @AsyncQueueMessage 注解不会被解析。
确保 config/autoload/async_queue.php 中 'processes' 值大于 0,例如 'processes' => 1 —— 【这是消费者进程能否启动的硬性前提】,设为 0 将导致整个异步队列静默失效。
运行 php bin/hyperf.php start 后,控制台应出现 Process[AsyncQueueProcess] start 日志,否则说明进程未注册或配置未生效。
定义带 @AsyncQueueMessage 注解的方法
在任意 Service 类中(如 app/Service/OrderService.php),添加一个 public 方法,并在其上方标注 @AsyncQueueMessage:
方法一:最简写法(无参数)#[AsyncQueueMessage]public function sendNotification(): void { echo '通知已异步发送'; }
方法二:带参数(参数会自动序列化进队列)#[AsyncQueueMessage]public function processOrder(int $orderId, string $status): void { // 处理逻辑 }
注意:参数类型必须是可序列化的(int/string/array/object),不能传 resource、Closure 或未实现 Serializable 的自定义对象——【传入 Closure 会导致反序列化失败并静默丢弃任务】。
调用注解方法触发投递
第一步:在控制器或任意业务代码中获取该 Service 实例:$orderService = $this->container->get(OrderService::class);
第二步:直接调用被注解的方法:$orderService->processOrder(1001, 'paid');
这一步不会同步执行方法体,而是由 Hyperf 的 AOP 拦截器捕获调用,自动将方法名、参数、类名打包成任务,推入 Redis 队列 channel。整个过程对业务代码完全透明,无需感知 Job 类或 push 操作。
第三步:消费者进程从 Redis 读取该任务,反序列化参数,再反射调用原方法——此时才真正执行 processOrder 内部逻辑。
定制投递行为(可选)
① 指定队列通道:#[AsyncQueueMessage(channel: 'order')],对应 async_queue.php 中同名配置项,用于隔离不同业务队列。
② 设置延迟执行(毫秒级):#[AsyncQueueMessage(delay: 60000)],表示 60 秒后执行;注意:Hyperf 3.1 默认使用 Redis ZSET 实现延时,需确保 delay_queue.php 已正确配置且专用 delayed 进程已启用。
③ 控制重试次数:#[AsyncQueueMessage(maxAttempts: 3)],失败后最多重试 2 次(即总共执行 3 次),超过则进入失败队列(需手动清理或监听失败事件)。











