yii2-queue的amqp_interop驱动需在console/config/main.php中配置,含host、port、user、password、vhost等连接参数,并在bootstrap中加入'queue';ttr为单次执行超时(秒),attempts为消息最多投递次数(含首次)。

RabbitMQ 连接在 Yii 中不是“配好就能用”,关键看用的是哪套驱动——原生 php-amqplib、yii2-queue 的 AMQP 驱动,还是自研封装,三者配置位置、参数含义、错误表现完全不同。
yii2-queue 的 amqp_interop 驱动怎么配连接参数
这是目前最主流的集成方式,配置必须放在 console/config/main.php(非 web 配置),且需确保 bootstrap 数组里有 'queue':
-
host、port、user、password、vhost是基础连接项,缺一不可;vhost默认是'/',但若 RabbitMQ 里建了自定义 vhost(比如myvhost),这里必须写成'myvhost',否则报CHANNEL_ERROR - access refused -
queueName是队列名,不是交换机名;它会自动声明(durable=true),但不会自动绑定 —— 如果你用的是 direct/exchange 路由,得自己调用bind或改用amqp_lib手动管理 -
ttr和attempts不是重试控制开关:前者是单次任务执行的硬超时(单位秒),后者是该消息最多被投递几次(含首次);设attempts => 3并不等于“失败后立刻重试 2 次”,而是失败后约 1 秒再入队,共最多 3 次
用 php-amqplib 原生扩展时,连接异常常见在哪
这类写法自由度高,但容易漏掉底层细节,报错往往卡在连接建立或信道操作阶段:
- PHP 进程启动时就报
AMQPConnectionException: Connection refused:检查host和port是否可通(telnet 192.168.6.88 5672),确认 RabbitMQ 的epmd和rabbit进程都在运行,且防火墙放行了 5672 端口 - 调用
queue_declare时报PRECONDITION_FAILED - inequivalent arg 'durable' for queue:说明队列已存在,但之前声明时用了durable=false,现在代码里却是true;要么删掉旧队列(rabbitmqctl delete_queue queue_name),要么统一 durable 设置 - 消费者长期空跑无日志:检查是否忘了调用
$channel->basic_consume(...)启动消费循环,或者没写$channel->wait()阻塞等待消息
AMQP 扩展装了但 PHP 报 “Class 'AMQPConnection' not found”
这是 PECL amqp 扩展和 Composer php-amqplib 库混淆的典型症状 —— 两者 API 完全不兼容:
- 如果你用的是
php-amqplib(推荐,纯 PHP 实现),就别装 PECLamqp扩展,否则可能因版本冲突导致类加载失败;composer require php-amqplib/php-amqplib足够 - 如果你坚持用 PECL
amqp(C 扩展,性能略高),那必须用AMQPConnection、AMQPChannel这套类,不能混用PhpAmqpLib\Connection\AMQPStreamConnection - 验证是否生效:运行
php -m | grep amqp(PECL 扩展)或composer show | grep amqplib(Composer 包)
Supervisor 管理消费者时为什么静默退出
用 Supervisor 跑 php yii queue/listen 最容易踩的坑是日志和退出信号处理:
- 命令必须带
--verbose参数,否则失败时不输出错误也不退出进程,Supervisor 以为它还在跑,实际任务已卡死 - Supervisor 的
autorestart要设为true,但startsecs建议 ≥5,避免刚启动就因 ttr 超时被 kill 导致反复重启 - 如果消费者处理中抛出未捕获异常,默认行为是终止当前任务并计入
attempts;但若异常来自框架层(如 DB 连接中断),可能直接崩掉整个进程 —— 此时需要在 Job 类的execute()外加try/catch,并显式return false让队列机制接管重试逻辑
真正麻烦的从来不是连上 RabbitMQ,而是当 ttr 和业务耗时不匹配、attempts 被误读为“重试次数”、或者 Supervisor 日志里只有一行 Started process 再无下文时,你得知道去哪查、改哪行、为什么这么改。











