我們在AMQP及RabbitMQ概論中,介紹交換器類型的時候,就曾提到過Topic模式,該模式其實和ActiveMQ通配符式訂閱非常的類似,所以這裏我們就不過於詳細介紹了,直接來簡單看一下小例子吧。
和RabbitMQ中的Direct、Fanout模式類似,在使用時,我們只需將交換器的類型修改爲Topic
即可,然後我們通過生產者來發布消息,這裏我們就一共發佈了9條測試消息,如下:
public class TopicProducer {
//交換器名稱
public static final String EXCHANGE_NAME = "logs";
public static void main(String[] args) throws Exception {
//創建連接,連接到RabbitMQ
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
Connection connection = connectionFactory.newConnection();
//創建信道
Channel channel = connection.createChannel();
//創建交換器
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
//定義的業務日誌消息級別,即作爲路由鍵使用
String[] logLevels = {"error.controller.A", "warn.controller.A", "info.controller.A",
"error.service.B", "warn.service.B", "info.service.B",
"error.mapper.C", "warn.controller.C", "info.controller.C"};
for (int i = 0; i < logLevels.length; i++) {
String logLevel = logLevels[i];
String msg = "Hello RabbitMQ";
//發佈消息,需要參數:交換器、路由鍵,其中以日誌消息級別爲路由鍵
channel.basicPublish(EXCHANGE_NAME, logLevel, null, msg.getBytes(Charset.forName("UTF-8")));
}
channel.close();
connection.close();
}
}
然後我們來看一看消費者是如何通過#
、*
來獲取指定的消息的,這裏我們先來獲取所有的消息,如下:
public class TopicConsumer {
public static final String EXCHANGE_NAME = "logs";
public static void main(String[] args) throws Exception {
//創建連接,連接到RabbitMQ,與發送端一樣
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
Connection connection = connectionFactory.newConnection();
//創建信道
Channel channel = connection.createChannel();
//可不創建,由生產者進行創建
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
String queueName = channel.queueDeclare().getQueue(); //聲明一個隨機隊列
channel.queueBind(queueName, EXCHANGE_NAME, "#");
//聲明瞭一個消費者
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = "Exchange: " + envelope.getExchange() + ", " +
"RoutingKey: " + envelope.getRoutingKey() + ", " +
"Content: " + new String(body, "UTF-8");
System.out.println(message);
}
};
//消費者正式開始在指定隊列上消費消息
channel.basicConsume(queueName, true, consumer);
}
}
上述我們使用了#
就獲取到了所有的消息,但是我們現在有改變需求了,只想獲取所有的error消息,那麼該如何進行處理呢?如下
那麼我們再來看看*
的用法,這裏再來獲取所有service的信息,如下:
看完上述的例子後,我們就可以更加容易理解AMQP及RabbitMQ概論中介紹的了,和ActiveMQ通配符式訂閱是介紹的只是符號存在差異而已。