RabbitMQ(7)Java Client - Topics

RabbitMQ(7)Java Client - Topics

Although using the direct exchange improved our system, it still has limitations - it can't do routing based on multiple criteria.

We want to subscribe to not only logs based on severity, but also based on the source which emitted the log.

Severity info/warn/critical
Facility   auth/cron/kern

Topic exchange
For topic exchange, routing_key must be a list of words.

The binding key must also be in the same form. The logic behind the topic exchange is similar to a direct one. A message sent with a particular rouing key will be delivered to all the queues that are bound with a matching binding key.

* (star) can substitute for exactly one word.
#(hash) can substitute for zero or more words.

We plan our routing key like this '<speed>.<colour>.<species>'.
Q1 "*.orange.*" is interested in all the orange animals
Q2 "*.*.rabbit" and "lazy.#" wants to hear everything about rabbits, and everything about lazy animals.

All come together
package com.sillycat.easytalker.rabbitmq.topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class EmitLogTopic {

private static final String EXCHANGE_NAME = "topic_logs";

private final static String SERVER_HOST = "localhost";

public static void main(String[] argv) {
Connection connection = null;
Channel channel = null;

try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SERVER_HOST);
connection = factory.newConnection();
channel = connection.createChannel();

channel.exchangeDeclare(EXCHANGE_NAME, "topic");

channel.basicPublish(EXCHANGE_NAME, "bird.white.fly", null,
"fly bird, haha.".getBytes());
channel.basicPublish(EXCHANGE_NAME, "bird.black.walk", null,
"walking cock!".getBytes());
channel.basicPublish(EXCHANGE_NAME, "lazy.black.sleep", null,
"sleep warm!".getBytes());
channel.basicPublish(EXCHANGE_NAME, "fast.white.rabbit", null,
"running fast rabbit!".getBytes());

} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
try {
connection.close();
} catch (Exception ignore) {
}
}
}
}

}

package com.sillycat.easytalker.rabbitmq.topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;

public class ReceiveLogsTopic1 {

private static final String EXCHANGE_NAME = "topic_logs";

private final static String SERVER_HOST = "rd.digby.com";

public static void main(String[] argv) {
Connection connection = null;
Channel channel = null;
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SERVER_HOST);
connection = factory.newConnection();
channel = connection.createChannel();

channel.exchangeDeclare(EXCHANGE_NAME, "topic");

String queueName = channel.queueDeclare().getQueue();

channel.queueBind(queueName, EXCHANGE_NAME, "lazy.#");

System.out
.println("
  • Waiting for messages. To exit press CTRL+C");
  • QueueingConsumer consumer = new QueueingConsumer(channel);
    channel.basicConsume(queueName, true, consumer);
    while (true) {
    QueueingConsumer.Delivery delivery = consumer.nextDelivery();
    String message = new String(delivery.getBody());
    String routingKey = delivery.getEnvelope().getRoutingKey();
    System.out.println(" [x] Received '" + routingKey + "':'"
    + message + "'");
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    if (connection != null) {
    try {
    connection.close();
    } catch (Exception ignore) {
    }
    }
    }
    }
    }

    ReceiveLogsTopic1 will receive all lazy animals. The only difference from ReceiveLogsTopic2 to ReceiveLogsTopic1 is as follow:
    channel.queueBind(queueName, EXCHANGE_NAME, "*.white.*");

    And ReceiveLogsTopic2 will focus on all the white colour animals.

    references:
    http://www.rabbitmq.com/tutorials/tutorial-five-java.html




    猜你喜欢

    转载自sillycat.iteye.com/blog/1579464