Hyperf异步队列需五步实现:装组件并验Redis连接;配置driver、channel、retry_seconds、handle_timeout、concurrent.limit五项关键参数;编写继承Job类且handle无参的测试任务;通过手动push或@Asynchronous注解投递;启动消费者进程后观察Redis队列、日志及失败重试全流程。

想让电商订单创建后立刻返回成功、不卡住用户,又确保库存扣减和消息推送在后台稳稳执行,就得搞懂Hyperf异步队列怎么把任务从主流程里“摘出来”再安全塞进Redis、由独立协程工人拉出来跑完——这不是加个注解就完事,得看清数据流向和协程调度的真实链条。
第一步:装好组件并确认Redis连接可用
运行 composer require hyperf/async-queue 安装组件,这一步必须成功,否则后续所有配置都无效。
检查 config/autoload/redis.php 中是否已正确定义 【default】 连接池,host、port、auth、db 值需与实际 Redis 服务完全一致;若用 Docker 或远程 Redis,请确保网络连通且防火墙放行端口。
执行 php bin/hyperf.php vendor:publish hyperf/async-queue 生成默认队列配置文件,它会落地到 config/autoload/async_queue.php。
第二步:理解 async_queue.php 里真正起作用的5个键
打开刚生成的 config/autoload/async_queue.php,只盯住这五个字段,其余可先忽略:
driver:必须是 Hyperf\AsyncQueue\Driver\RedisDriver::class,改成本地数据库驱动会导致延迟任务丢失、重试失效;
channel:就是 Redis 的 List 键名,默认 'queue',多个环境建议加前缀如 'prod:queue' 避免混用;
retry_seconds:任务执行抛异常后,隔多少秒重试,默认 5 秒,太短会压垮下游,太长影响时效性;
handle_timeout:单个任务最多允许执行几秒,超时会被强制终止并计入失败队列,【必须小于 PHP-FPM 或 Swoole 的 request timeout】;
concurrent.limit:同一时间最多有几个协程在消费任务,设为 10 表示最多 10 个任务并发执行,不是越多越好——CPU 核数 × 2 是较稳妥的起点。
第三步:写一个能验证成功的 Job 类
在 app/Job 目录下新建 TestQueueJob.php:
继承 Hyperf\AsyncQueue\Job,定义 public 属性接收参数,handle() 方法里只做两件事:记录日志 + 主动抛异常(用于验证重试)。
代码必须包含 public function handle() 方法,且不能带任何参数——参数只能通过构造函数传入并赋值给 public 属性,否则框架无法反序列化执行。
示例:
namespace App\Job;use Hyperf\AsyncQueue\Job;class TestQueueJob extends Job{ public $msg; public function __construct(string $msg) { $this->msg = $msg; } public function handle() { file_put_contents('/tmp/queue_test.log', $this->msg . PHP_EOL, FILE_APPEND); throw new \Exception('intentional fail'); }}
第四步:投递任务并启动消费者进程
方法一:控制器中手动投递
在任意 Controller 方法内,用 $this->container->get(\Hyperf\AsyncQueue\Driver\DriverFactory::class)->push(new \App\Job\TestQueueJob('hello from http')); 投递。
方法二:使用注解自动投递(推荐)
在 Job 类上加 #[Asynchronous] 注解(需先 composer require hyperf/asynchronous),然后直接 new 并调用即可,框架自动捕获并推入队列。
启动消费者进程:php bin/hyperf.php start,此时终端应出现 [INFO] Start consumer process: Hyperf\AsyncQueue\Process\ConsumerProcess 日志行。
检查 ps aux | grep ConsumerProcess,确认进程存活;若无输出,说明 config/autoload/processes.php 没有正确注册 Hyperf\AsyncQueue\Process\ConsumerProcess::class。
第五步:观察任务从入队到失败重试的完整生命周期
第一步:查看 Redis 中队列长度
用 redis-cli -a yourpass 连入 Redis,执行 LLEN queue(或你配置的 channel 名),确认数字 > 0。
第二步:等待 5 秒后再次执行 LLEN queue,数值应不变——因为任务已被消费者取出,正在执行中。
第三步:查看 /tmp/queue_test.log,确认第一行日志已写入;同时检查 runtime/logs/hyperf.log,搜索 TestQueueJob,应看到类似 Job App\Job\TestQueueJob failed after 3 attempts 的报错记录。
第四步:执行 php bin/hyperf.php async-queue:failed,列出所有失败任务 ID;再执行 php bin/hyperf.php async-queue:retry {id} 可手动重试指定任务。


















