必须将耗时操作丢进异步队列后台执行,hyperf 2.2 的 async-queue 组件默认基于 redis,需安装组件、生成配置文件、确保 config/autoload/async_queue.php 存在且 'processes' > 0,否则消费者进程无法启动。

要在 Hyperf 2.2 中让耗时操作不卡住用户请求,必须把任务丢进异步队列后台执行——比如下单后发短信、生成报表、同步第三方数据,这些都不能让用户干等。Hyperf 2.2 的 async-queue 组件默认基于 Redis,配置轻、启动快、失败可重试,但漏掉一个配置项就根本跑不起来。
安装与基础配置
执行命令安装组件:
composer require hyperf/async-queue
运行命令生成默认配置文件:
php bin/hyperf.php vendor:publish hyperf/async-queue
检查 config/autoload/async_queue.php 是否已生成。若未生成或为空,【该文件缺失会导致消费者进程完全不启动】,后续所有投递都石沉大海。
确认配置中 'processes' 值大于 0(例如设为 1),否则即使其他全对,消费者进程也不会被拉起——这是 Hyperf 2.2 最隐蔽的启动失败原因。
编写任务类并投递
在 app/Job 目录下新建 SendSmsJob.php:
namespace App\Job;
use Hyperf\AsyncQueue\Job;
class SendSmsJob extends Job
{
public string $phone;
public string $content;
public function __construct(string $phone, string $content)
{
$this->phone = $phone;
$this->content = $content;
}
public function handle()
{
// 这里写真实发短信逻辑,如调用 SDK
file_put_contents('/tmp/sms.log', "send to {$this->phone}: {$this->content}\n", FILE_APPEND);
}
}
在控制器中使用 DI 获取队列服务并投递:
$job = new SendSmsJob('13800138000', '验证码:123456');
$container->get(\Hyperf\AsyncQueue\Driver\DriverFactory::class)->push($job);
注意:不要直接 new Job() 后调 handle(),那只是同步执行,没走队列。
启用消费者进程
打开 config/autoload/processes.php,确保包含以下内容:
return [
Hyperf\AsyncQueue\Process\ConsumerProcess::class,
];
重启服务:
php bin/hyperf.php start
启动成功后,控制台应出现类似 Process[ConsumerProcess] start 的日志;若无此日志,说明 ConsumerProcess 未被加载,大概率是 processes.php 文件未正确修改或路径错误。
运行 ps aux | grep 'ConsumerProcess',确认进程数量与 async_queue.php 中 'processes' 设置一致——比如设为 2,就该看到两个对应进程。
验证任务是否真正执行
方法一:手动触发投递后,立即检查 /tmp/sms.log 是否新增一行记录;没有则说明任务未消费,重点排查 Redis 连接池是否可用、channel 名称是否与配置一致。
方法二:在 handle() 方法开头加入 die('consumed');,访问一次接口,若页面输出 consumed,说明任务已被消费并执行;若无输出,说明消息卡在队列里没被捞走。
方法三:使用 Redis CLI 查看队列长度:
redis-cli -n 0 llen async-queue
如果数值持续 > 0 且 log 无新增,说明消费者进程异常退出或未连接到正确 Redis DB。











