RabbitMQ discards messages if their routing key doesn't match any queues bound to the exchange. When you start MQSender
first, no queues are bound, so the messages it sends are lost. When you start MQReceiver
, it binds queues to the exchange, so RabbitMQ has a place to put the message from MQSender
. When you stop MQReceiver, since you created an anonymous queue, the queue and all bindings are removed from the exchange.
If you want messages to be stored on the server while MQReceiver
is not running, you need the receiver to create a named queue, and bind the routing keys to that queue. Note that creating a named queue is idempotent, and the queue won't be created if it already exists. Then you need the receiver to pull messages off the named queue.
Change your code to look something like this:
MQSender
....
String namedQueue = "logqueue";
//declare named queue and bind log level routing keys to it.
//RabbitMQ will put messages with matching routing keys in this queue
channel.queueDeclare(namedQueue, false, false, false, null);
for (int level = 0; level < LOG_LEVELS.length; level++) {
channel.queueBind(namedQueue, EXCHANGE_NAME, LOG_LEVELS[level]);
}
...
MQReceiver
...
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
QueueingConsumer consumer = new QueueingConsumer(channel);
//Consume messages off named queue instead of anonymous queue
String namedQueue = "logqueue";
channel.basicConsume(namedQueue, true, consumer);
while(true) {
...