必须配置独立日志通道、异常捕获与prometheus指标采集,才能实现hyperf异步队列失败告警闭环:新增async_queue日志通道并关联warning级别,手动或事件监听记录失败日志,埋点上报失败指标,通过grafana+钉钉实现5分钟失败率超20%实时告警。

在生产环境中,Hyperf异步队列任务失败后无声沉底、重试耗尽却无通知、积压任务无法及时发现——这些问题必须通过日志监控与告警闭环解决。
配置队列任务执行日志通道
第一步:打开 config/autoload/logger.php,在 channels 数组中新增名为 async_queue 的独立日志通道。
第二步:该通道的 handler 必须使用 RotatingFileHandler,构造参数中 filename 设为 BASE_PATH . '/runtime/logs/async-queue.log',maxFiles 设为 15,启用 compress => true。
第三步:在该通道的 processors 中加入 Hyperf\Logger\Processor\CoroutineContextProcessor::class,确保每条日志自动携带协程 ID 和请求上下文。
第四步:修改 default 通道的 handlers,将其中一条 handler 的 level 改为 Logger::WARNING,并把 channel 指向刚创建的 async_queue ——这一步不改,失败日志就进不了独立通道。
捕获并记录队列异常事件
方法一:在自定义 Job 的 handle() 方法最外层加 try-catch:
捕获所有异常后,调用 $this->logger->error('Async job failed', ['job' => get_class($this), 'params' => $this->params, 'exception' => $e->getMessage()]);【必须手动记录,否则 silent fail】
方法二:监听 Hyperf 内置事件 Hyperf\AsyncQueue\Event\AfterHandle 和 Hyperf\AsyncQueue\Event\Failed:
在 config/autoload/listeners.php 中注册监听器,对 Failed 事件强制写入 async_queue 通道,并附加 retry_count 和 fail_time 字段。
接入 Prometheus 实时采集队列指标
执行命令安装依赖:composer require hyperf/metric promphp/prometheus_client_php。
确认 config/autoload/metric.php 中已启用 prometheus 驱动,且 scrape_port 设置为 9502(不能与 HTTP 服务端口冲突)。
在 Job 类的 handle() 方法开头添加计数器埋点:$counter = $this->metricFactory->makeCounter('async_job_processed_total', ['status', 'job']); $counter->with('success', get_class($this))->add(1);
在 Failed 事件监听器中同步上报失败计数:$counter->with('failed', get_class($job))->add(1); —— 这是告警触发的唯一数据源。
配置 Grafana 告警看板与钉钉通知
① 登录 Grafana,在「Alerting」→「Contact points」中新建一个钉钉 contact point,填入 Webhook 地址和 secret(需提前在钉钉群机器人设置中获取)。
② 创建新告警规则,Expression 填写:rate(async_job_processed_total{status="failed"}[5m]) > 0.2,即 5 分钟内失败率超 20% 触发。
③ 在 Rule message 中插入变量:{{ $labels.job }} 连续失败 {{ $value | printf "%.1f" }} 次/分钟,当前积压 {{ (sum by(job)(rate(async_job_processed_total{status="failed"}[5m]))) | printf "%.0f" }} 条。
④ 保存后,立即点击「Test rule」验证钉钉是否收到测试消息。若未收到,检查 Hyperf 进程是否已重启以加载 metric 配置。
⑤ 手动触发一次失败任务(例如在 Job 中 throw new RuntimeException('test fail')),等待 5 分钟后确认告警是否准确推送。











