在RabbitMQ中,为什么Exchange会在第二次运行时接受消息?

时间:2013-09-24 12:57:00

标签: php rabbitmq amqp

情况如此。

我正在使用PHP PECL AMQP RabbitMQ客户端。当我第一次尝试发送消息进行交换时,没有任何反应。似乎消息尚未发送,AMQPQueue :: get不返回任何内容,即使AMQPExchange :: publish返回true。

之后(即第二次交换声明后)一切正常。

它有什么用?

UPD。代码示例。

<?php
$connection = new AMQPConnection;
//config...
$connection->connect();

$channel = new AMQPChannel($connection);

$exchange = new AMQPExchange($channel);
$exchange->setName('test_exchange');
$exchange->setType(AMQP_EX_TYPE_DIRECT);
$exchange->declareExchange();
$exchange->setFlags(AMQP_DURABLE);

$exchange->bind('test_exchange', 'test_routing_key');
$exchange->publish('test_message', 'test_routing_key');

$queue = new AMQPQueue($channel);
$queue->setName('test_routing_key');
$queue->declareQueue();
$queue->bind('test_exchange', 'test_routing_key');
var_dump($queue->get(AMQP_AUTOACK));

1 个答案:

答案 0 :(得分:2)

发布和路由之间存在差异: 发布意味着将消息发送到交换,而路由意味着将消息交换发送到绑定实体(例如队列或其他交换)。

您的第一条消息已发布,但未被路由,因为当时没有队列绑定到具有匹配路由键的交换机。 AMQPExchange :: publish returns true只是确认交换收到了消息。

请参阅this picture部分中的RabbitMQ - AMQP 0-9-1 Model Explained

如果你肯定需要知道消息是否被路由到至少一个队列,你可以设置强制标志:(RabbitMQ - Reliability Guide

  

如果消息可能以更复杂的方式路由,但生产者仍然需要知道他们是否至少到达一个队列,它可以在basic.publish上设置强制标志,确保basic.return(包含回复代码)如果没有适当的约束队列,将会发回一些文字说明。