相关环境:PHP7.4 + RabbitMQ 3.3.5 + Laravel8
生产者代码:
public function sendBasicMsg() {
try {
$connection = new AMQPStreamConnection('127.0.0.1', 5672, 'guest', 'guest');
$channel = $connection->channel();
$queue = 'record-queue'; //队列名称
//queue_declare第三个参数设置true代表开启队列持久化
$channel->queue_declare($queue, false, true, false, false);
$data = [
'name' => 'YIF'
];
//DELIVERY_MODE_PERSISTENT设置消息持久化
$msg = new AMQPMessage(json_encode($data), ['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);
$channel->basic_publish($msg, '', $queue);
echo " [x] Sent 'success'\n";
$channel->close();
$connection->close();
} catch (\Exception $e) {
Log::error("生产者发送消息异常:", [
'method' => __METHOD__,
'respone' => $e->getMessage() ?? ""
]);
}
}
生产者开启了队列,消息的持久化。
通过生产者生产了几条消息,来看看消费者代码:
public function consume($consumeName)
{
try {
$connection = new AMQPStreamConnection('127.0.0.1', 5672, 'guest', 'guest');
$channel = $connection->channel();
$queue = 'record-queue'; //队列名称
//没有开启队列持久化
$channel->queue_declare($queue, false, false, false, false);
$callback = function ($msg) use ($consumeName) {
Log::info($consumeName . ' 消费啦===》' . $msg->body);
$msg->ack(); //发送ack
};
//第四个参数为false意味着要ack (true 意味着不响应ack)
$channel->basic_consume($queue, '', false, false, false, false, $callback);
while ($channel->is_open()) { //一直监听
$channel->wait();
}
$channel->close();
$connection->close();
} catch (\Exception $e) {
Log::error("消费者消费消息异常:", [
'method' => __METHOD__,
'respone' => $e->getMessage() ?? ""
]);
}
}
当运行消费者代码的时候报错:PRECONDITION_FAILED - parameters for queue 'record-queue' in vhost '/' not equivalent
解决办法就是在消费者队列声明时,加上可持久化参数。
$channel->queue_declare($queue, false, true, false, false);
基本这种问题都是生产者与消费者两边的配置设置不一样导致的!