Webman Redis队列积压需检查重启消费者、扩展并发数、修复阻塞任务、手动清理分流、监控失败队列;1. 用ps查进程并php webman restart;2. 调整process.php中count值;3. 加耗时监控与超时设置;4. redis-cli导出截断后分批重投;5. 定期检查redis-queue-failed并手动重试。

Webman 处理大流量异步任务,核心不在“集成哪个队列”,而在于消费者能否扛住压、任务是否卡死、积压后能否快速止损。Redis 队列(webman/redis-queue)是默认轻量选择,但一旦消息突增或单条任务耗时失控,llen queue_name 就会持续上涨,CPU 占用却可能很低——这说明不是没资源,而是被阻塞了。
怎么确认 Redis 队列消费者真正在干活
别只看 php webman start 是否执行成功。真实运行中,消费者进程可能已僵死或陷入无限等待。
- 执行
ps aux | grep redis-queue,确认有活跃的 PHP 进程,且TIME列在缓慢增长(不是恒为00:00:00) - 进 Redis 执行
llen webman:queue:default,再等 10 秒重查,值没降?说明没消费或消费极慢 - 检查
storage/logs/redis-queue.log,重点搜Exception或timeout,常见如Redis::blpop(): read error on connection表示连接中断未重连 - 临时加一行日志到
app/queue/Handler.php::handle()开头:file_put_contents('/tmp/queue_trace.log', date('H:i:s') . " start\n", FILE_APPEND);,观察日志是否持续追加
为什么调高 count 有时反而更卡
并发数不是越多越好。Webman 的 Redis 消费者共享同一套 Redis 连接池,默认每个 Worker 进程独占一个 Predis\Client 实例。若 count => 8 但 Redis 服务器 maxclients 设为 100,8 个消费者 + 其他业务请求很容易打满连接,引发超时雪崩。
- 先查 Redis 配置:
redis-cli config get maxclients,生产环境建议 ≥ 500 - 检查 Webman 的 Redis 连接配置(
config/redis.php),把'pool' => ['max_connections' => 20]改为匹配消费者数 × 2,例如count => 4时设为10 -
process.php中的count建议从2起步,每轮压测后观察redis-cli info clients | grep connected_clients是否逼近上限
任务里藏着“定时炸弹”:同步调用不加超时
一个 file_get_contents('https://api.example.com') 没设超时,就能让整个消费者进程挂住 60 秒,期间其他消息全堵在 BLPOP 队列头,无法拉取。
- 禁用所有裸
file_get_contents、curl_exec,改用GuzzleHttp\Client并强制设置:'timeout' => 3.0, 'connect_timeout' => 1.5 - 数据库查询必须走框架封装的连接池,避免
new PDO()直连;检查config/database.php中'wait_timeout'是否 ≤ 2 秒 - 在
handle()开头加监控:$start = microtime(true);,结尾加判断:if (microtime(true) - $start > 2.5) { \Log::warning('Slow queue task', ['cost' => round(microtime(true) - $start, 3)]); }
积压已发生,手动清理要分三步走
别直接 LTRIM 截断,否则失败消息永久丢失。得先捞出、再分流、最后补漏。
- 导出积压消息:
redis-cli lrange webman:queue:default 0 9999 > dump.json(注意:Redis 7+ 支持LGET,旧版用LRANGE分批) - 用脚本解析
dump.json,过滤出明显异常的任务(如含"retry": 3或"failed_at"字段),单独写入failed_batch.json - 对剩余健康消息,用
redis-cli ltrim webman:queue:default 10000 -1截断头部,再用LPUSH分批重投(每次 ≤ 100 条,避免单次命令阻塞) - 最后检查
redis-queue-failedkey,用redis-cli lrange redis-queue-failed 0 -1看失败详情,挑关键任务手动redis-queue:retry命令重试
最易被忽略的是消费者进程的内存泄漏——长期运行后 memory_get_usage() 持续上涨,最终 OOM 被系统 kill。务必在 handle() 结尾加 gc_collect_cycles(),并定期重启消费者(例如每天凌晨 php webman restart)。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











