yii2.0.48中启用rabbitmq需绕过默认驱动,使用php-amqplib 2.9.x版本,配置host/port/user/password/vhost/queue_name/exchange/exchange_type,注册queue组件于console.php,任务类实现jobinterface,通过php yii queue/run监听,推送任务须严格匹配配置队列名。

在 Yii2.0.48 中启用 RabbitMQ 作为消息队列,需绕过默认的 redis/beanstalk 驱动,直接对接 AMQP 协议;若沿用 yiiqueuemqp 组件但未正确声明交换机类型或未启用持久化,会导致消息发送后丢失、消费者无法拉取、队列自动删除等不可逆问题。
安装 RabbitMQ PHP 客户端依赖
执行 composer 命令安装官方 AMQP 库:composer require php-amqplib/php-amqplib ^2.9。注意:必须使用 2.9.x 版本,高于 3.0 的版本已移除对 AMQP 0.9.1 协议的向后兼容支持,Yii2.0.48 无法识别新接口。
安装前确认 php.ini 已启用 sockets 扩展——若未开启,AMQPStreamConnection 实例化会静默失败,后续所有连接操作均无报错但始终超时。
配置 RabbitMQ 连接参数
在 config/params.php 中添加以下配置:
'rabbitmq' => [ 'host' => 'localhost', 'port' => 5672, 'user' => 'guest', 'password' => 'guest', 'vhost' => '/', 'queue_name' => 'yii_default_queue', 'exchange' => 'yii_direct_exchange', 'exchange_type' => 'direct',],
【queue_name 和 exchange 必须显式指定,不可留空】——否则 yiiqueuemqpQueue 构造时会使用 null 值触发 AMQP 协议级错误,表现为 channel 关闭后无法重建。
注册 RabbitMQ 队列组件
打开 config/console.php(控制台应用配置),在 'components' 数组中加入:
'queue' => [ 'class' => yiiqueuemqpQueue::class, 'host' => $params['rabbitmq']['host'], 'port' => $params['rabbitmq']['port'], 'user' => $params['rabbitmq']['user'], 'password' => $params['rabbitmq']['password'], 'queueName' => $params['rabbitmq']['queue_name'], 'exchangeName' => $params['rabbitmq']['exchange'], 'exchangeType' => $params['rabbitmq']['exchange_type'], 'vhost' => $params['rabbitmq']['vhost'], 'serializer' => yiiqueueserializersPhpSerializer::class,],
这一步不能写在 web.php 中——RabbitMQ 队列消费必须由 console 应用启动,web 请求上下文无法维持长连接,会导致 channel 异常关闭。
创建可执行队列任务类
在 console/controllers 目录下新建 QueueController.php:
第一步:定义控制器继承 yiiconsoleController;
第二步:在 actionRun() 方法中调用 Yii::$app->queue->run() 启动监听;
第三步:确保该控制器类顶部引入命名空间 use yiiqueueJobInterface;;
第四步:在 console/migrations 下无需建表——RabbitMQ 自身管理队列,不依赖数据库。
运行命令:php yii queue/run。此时进程将阻塞并持续监听 yii_default_queue,收到消息后自动反序列化并执行 execute() 方法。
推送任务到 RabbitMQ 队列
方法一:在任意控制器或服务中调用
Yii::$app->queue->push(new ppjobsSendEmailJob(['to' => 'user@example.com']));
方法二:使用命令行快速测试
php yii queue/push "app\jobs\SendEmailJob" --to=user@example.com
注意:推送时若队列名与配置中 queueName 不一致,消息会被丢弃且无任何日志提示——RabbitMQ 默认拒绝路由到未声明的队列。











