hyperf异步队列redis超时问题根源在于连接池容量不足与pipeline未释放导致的协程连接泄漏;需检查established连接数、合理设置max_connections(40~60)、增加wait_timeout,并为pipeline/transaction添加finally兜底释放,同时为队列配置独立redis连接池。

Hyperf异步队列消费进程持续报Redis connection timeout或WaitTimeoutException,任务堆积、重试激增,但Redis服务本身ping得通、info正常,说明问题不在服务端存活状态,而藏在Hyperf的连接池调度与协程生命周期管理中。
确认是否为连接池耗尽导致的假性超时
第一步:登录运行ConsumerProcess的服务器,执行ss -s | grep ESTAB,观察当前ESTABLISHED连接数是否长期逼近pool.max_connections配置值。
第二步:检查config/autoload/redis.php中对应队列所用Redis连接池的max_connections。若业务峰值QPS为120、平均处理耗时0.15s,则理论需18连接,但必须设为【40~60】——留足协程上下文切换与pipeline残留缓冲空间。
第三步:临时将wait_timeout从默认的2.0改为5.0,重启ConsumerProcess。若超时错误明显减少但未消失,基本锁定为连接池容量不足而非网络或服务端问题。
排查pipeline/multi未释放引发的连接泄漏
方法一:在ConsumerProcess启动日志中搜索Hyperf\Redis\Redis::pipeline或multi调用痕迹,定位所有使用了管道或事务的Job类。
方法二:对疑似Job类的handle()方法添加强制兜底释放逻辑——在try块外加finally,显式调用$this->redis->reset()(仅限Hyperf 3.0+)或手动unset($this->redis)触发析构。
注意:【Hyperf 2.x中$redis->pipeline()后若中途throw Exception且无finally,连接将永久卡在该协程上下文中】,哪怕协程后续执行完毕也不归还连接池。
调整异步队列专属Redis连接池超时参数
打开config/autoload/async_queue.php,找到default配置项下的redis子项:
将'pool' => 'default'改为指向一个独立连接池名称,例如'pool' => 'queue';
在config/autoload/redis.php中新增名为queue的连接池配置,其中必须包含:
'options' => [Redis::OPT_READ_TIMEOUT => -1, Redis::OPT_SERIALIZER => Redis::SERIALIZER_PHP];
设置'max_connections' => 50、'wait_timeout' => 3.0、'retry_seconds' => [1, 3, 7];
保存后执行php bin/hyperf.php start重启服务。











