RabbitMQ消息发送验证方法及队列idle状态相关疑问
RabbitMQ消息验证与队列状态问题解析
队列idle转running的触发条件
队列显示idle意味着当前没有活跃消费者连接并监听该队列。当有消费者成功连接到队列,并且处于等待接收消息的状态时,队列状态就会切换为running。
验证消息发送成功的实用方法
1. 后台可视化查看
登录RabbitMQ管理后台,进入log队列的详情页:
- 查看
Messages区域的Ready数值:如果消息发送成功且未被消费,该数值会对应增加(比如运行一次生产者脚本,数值+1) - 查看
Unacknowledged:若有消费者正在处理消息,该数值会动态变化
2. 代码层面添加发布确认(最可靠)
给生产者代码加上RabbitMQ的发布确认机制,让服务器在消息成功路由到队列后返回确认信号,修改后的代码如下:
require_once __DIR__ . '/vendor/autoload.php'; use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage; $host = "ip.address"; $port = 5672; $username = "username"; $password = "password"; $exchangeName = "@frontend-api/log"; $queueName = "log"; $connection = new AMQPStreamConnection($host, $port, $username, $password); $channel = $connection->channel(); // 启用发布确认模式 $channel->confirm_select(); // 声明交换机 $channel->exchange_declare( $exchangeName, 'direct', false, true, false ); $channel->queue_declare($queueName, false, true, false, false); $channel->queue_bind($queueName, $exchangeName, "log"); $message = new AMQPMessage('Hello World!'); // 注意添加路由键,和绑定队列时的路由键一致 $channel->basic_publish($message, $exchangeName, "log"); // 等待RabbitMQ返回确认,超时5秒 if ($channel->wait_for_pending_acks_returns(5)) { echo " [x] 消息已被RabbitMQ确认接收\n"; } else { echo " [!] 消息发送失败或未收到确认\n"; } echo " [x] Sent 'Hello World!' "; $channel->close(); $connection->close();
3. 编写测试消费者验证
写一个简单的消费者脚本,订阅log队列,看是否能接收到消息:
require_once __DIR__ . '/vendor/autoload.php'; use PhpAmqpLib\Connection\AMQPStreamConnection; $host = "ip.address"; $port = 5672; $username = "username"; $password = "password"; $queueName = "log"; $connection = new AMQPStreamConnection($host, $port, $username, $password); $channel = $connection->channel(); $channel->queue_declare($queueName, false, true, false, false); echo " [*] 等待消息,按Ctrl+C退出\n"; $callback = function ($msg) { echo ' [x] 收到消息:', $msg->body, "\n"; }; $channel->basic_consume($queueName, '', false, true, false, false, $callback); while ($channel->is_consuming()) { $channel->wait(); } $channel->close(); $connection->close();
运行这个消费者脚本后,再执行你的生产者脚本,如果消费者能打印出Hello World!,就说明消息确实发送成功。
你现有代码的小问题
你当前的basic_publish调用没有指定路由键,但之前绑定队列时用了路由键"log",而direct类型交换机需要路由键匹配才能把消息投递到队列。所以要修改basic_publish的第三个参数:
// 原代码 $channel->basic_publish($message, $exchangeName); // 修改为 $channel->basic_publish($message, $exchangeName, "log");
不指定路由键的话,消息可能会被交换机丢弃,这也是你看不到消息的潜在原因。
内容的提问来源于stack exchange,提问作者Sidney Sousa
相关产品推荐
相关产品推荐

