我试图弄清即使没有消费者在运行,是否也可以在RabbitMQ交换中存储消息。
我(很可能是错误地)理解,要实现交换需要“持久”以及队列和消息需要带有“持久”标记来发出
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT
我的主要目标是将所有消息存储在交换中,以便在由于某种原因而没有使用者在运行的情况下,当我启动一个时,交换中的所有消息都可以定向到绑定队列。 我声明我的交流和排队如下:
//Sender.php
public function sendToQueue(ActionMessage $message)
{
$headers = [
'content-type' => 'application/json',
'timestamp' => $message->getCreatedAt()->getTimestamp(),
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT
];
$channel = $this->connection->getChannel();
$channel->exchange_declare($this->exchangeName, 'direct', false, true, false);
$qMessage = new AMQPMessage(json_encode($message->toArray()), $headers);
$channel->basic_publish($qMessage, $this->exchangeName, $message->getTopic());
return true;
}
//Receiver.php
public function consume($callbackFunction)
{
$channel = $this->messenger->getChannel();
$channel->exchange_declare($this->exchange, 'direct', false, true, false);
list($queueName, ,) = $channel->queue_declare('', false, true, true, false);
$channel->queue_bind($queueName, $this->exchangeName, $this->topicAction);
$channel->basic_consume($queueName, '', false, true, false, false, $callbackFunction);
while (count($channel->callbacks)) {
$channel->wait();
}
$channel->close();
$this->messenger->close();
}
我将不胜感激(即使只是放弃这个想法并在两者之间插入一些存储空间)。 谢谢。
答案 0 :(得分:0)
交换不存储消息,这是队列的工作。您遇到的问题不是没有消费者在运行,而是没有队列存在,因为您已经离开了消费者声明自己的队列。
如果您希望消息在接收者收到之前一直保持不变,则应声明:
direct
交换,则为每个路由密钥一个)它们都可以在Sender脚本中声明,但是在大多数情况下,在部署应用程序时将它们声明一次更为有意义,就像对待数据库架构一样对待它们。
您可以直接附加到命名队列,然后开始接收在那里等待的消息,而不是在Receiver脚本中创建匿名队列。
这将带来的主要区别是同一路由密钥的多个使用者如何交互:
您可能会发现this RabbitMQ simulator对于可视化差异很有用。
您可能会发现自己确实想要混合食物:
最后一点,RabbitMQ中有两种机制可以对无法处理的消息进行不同处理:
如果您实际上不想正常处理丢失的消息,而只是想检测它们,例如,AE可能在您的示例中很有用。将它们列出在错误日志中。