rabbitmq主题模式
rabbitmq主题模式
主题模式可以实现动态路由的匹配,对应的交换机类型为topic
topic交换机的routingKey不能随意写,它必须是一个单词列表,以点号分隔开。这些单词可以是任意单词,eg:"stock.usd.nyse"、 "nyse.vmw"、"quick.orange.rabbit"。且这个单词列表最多不能超过 255 个字节
在这个规则列表中,其中有两个替换符是大家需要注意的
*(星号)可以代替一个单词#(井号)可以替代零个或多个单词
当队列绑定关系是下列这种情况时需要引起注意
- 当一个队列绑定键是
#,那么这个队列将接收所有数据,就有点像fanout - 如果队列绑定键当中没有
#和*出现,那么该队列绑定类型就是direct
代码实现

设置消费者A的routingKey为*.b.*,注意:声明的交换机类型为BuiltinExchangeType.TOPIC
package com.yl.topic;
import com.rabbitmq.client.*;
import com.yl.util.RabbitConstant;
import com.yl.util.RabbitUtils;
import java.io.IOException;
/**
* 消费者A
*
* @author Y-wee
*/
public class TopicConsumerA {
public static void main(String[] args) throws IOException {
Connection connection = RabbitUtils.getConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(RabbitConstant.EXCHANGE_TOPIC, BuiltinExchangeType.TOPIC);
channel.queueDeclare(RabbitConstant.QUEUE_TOPIC_A,false,false,false,null);
channel.queueBind(RabbitConstant.QUEUE_TOPIC_A, RabbitConstant.EXCHANGE_TOPIC,"*.b.*");
DeliverCallback deliverCallback = (consumerTag, message) -> {
System.out.println("ConsumerA接收到消息:"+new String(message.getBody()));
channel.basicAck(message.getEnvelope().getDeliveryTag(),false);
};
CancelCallback cancelCallback = (consumerTag) -> {
System.out.println("消费失败");
};
channel.basicConsume(RabbitConstant.QUEUE_TOPIC_A, false, deliverCallback, cancelCallback);
}
}
RabbitUtils是笔者自定义的一个工具类,用来获取连接
RabbitConstant是笔者自定义的一个常量类,里面存储了队列名和交换机名
设置消费者B的routingKey为*.*.c和a.#
package com.yl.topic;
import com.rabbitmq.client.*;
import com.yl.util.RabbitConstant;
import com.yl.util.RabbitUtils;
import java.io.IOException;
/**
* 消费者B
*
* @author Y-wee
*/
public class TopicConsumerB {
public static void main(String[] args) throws IOException {
Connection connection = RabbitUtils.getConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(RabbitConstant.EXCHANGE_TOPIC, BuiltinExchangeType.TOPIC);
channel.queueDeclare(RabbitConstant.QUEUE_TOPIC_B,false,false,false,null);
channel.queueBind(RabbitConstant.QUEUE_TOPIC_B, RabbitConstant.EXCHANGE_TOPIC,"*.*.c");
channel.queueBind(RabbitConstant.QUEUE_TOPIC_B, RabbitConstant.EXCHANGE_TOPIC,"a.#");
DeliverCallback deliverCallback = (consumerTag, message) -> {
System.out.println("ConsumerB接收到消息:"+new String(message.getBody()));
channel.basicAck(message.getEnvelope().getDeliveryTag(),false);
};
CancelCallback cancelCallback = (consumerTag) -> {
System.out.println("消费失败");
};
channel.basicConsume(RabbitConstant.QUEUE_TOPIC_B, false, deliverCallback, cancelCallback);
}
}
生产者发送消息
package com.yl.topic;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.yl.util.RabbitConstant;
import com.yl.util.RabbitUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 生产者
*
* @author Y-wee
*/
public class TopicProvider {
public static void main(String[] args) throws IOException {
Map<String, String> map = new HashMap<>();
map.put("aaa.b.ccc","b");
map.put("aa.bb.c","c");
map.put("a.bbb.ccc.ddd","a");
Connection connection = RabbitUtils.getConnection();
Channel channel = connection.createChannel();
for(String key:map.keySet()){
channel.basicPublish(RabbitConstant.EXCHANGE_TOPIC,key,null,map.get(key).getBytes());
}
System.out.println("消息发送完毕");
}
}
控制台打印结果:
TopicConsumerA
ConsumerA接收到消息:b
TopicConsumerB
ConsumerB接收到消息:a
ConsumerB接收到消息:c
记得快乐
浙公网安备 33010602011771号