扇型交换机将消息路由给绑定到它身上的所有队列,而不会理会绑定的路由键。如果 N 个队列绑定到某个扇型交换机上,当有消息发送给此扇型交换机时,交换机会将消息的拷贝分别发送给这所有的 N 个队列。扇型用来交换机处理消息的广播路由。
因为扇型交换机投递信息的拷贝到所有绑定到它的队列,所以它可以用来在群聊的时候,分发消息给参与群聊的用户。
扇型交换机图例:
在这种模式下,消息发送流程是这样的:
// 将通道声明指定的交换机
// 参数1:交换机的名称
// 参数2:交换机的类型
channel.exchangeDeclare("logs","fanout");
// 发送消息
channel.basicPublish("logs","",null,"fanout type message".getBytes());
// 通道声明交换机
channel.exchangeDeclare("logs","fanout");
// 临时队列
String queueName = channel.queueDeclare().getQueue();
// 队列绑定交换机
channel.queueBind(queueName,"logs","");
实例代码:
Runnable myRunnable = () -> {
try {
Connection conn = RabbitMQUtils.getConnection();
Channel channel = conn.createChannel();
// 通道声明交换机
channel.exchangeDeclare("logs", "fanout");
// 临时队列
String queueName = channel.queueDeclare().getQueue();
// 队列绑定交换机
channel.queueBind(queueName, "logs", "");
// 消费消息
channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者" + consumerTag + ":" + new String(body));
}
});
} catch (IOException e) {
e.printStackTrace();
}
};
Thread t1 = new Thread(myRunnable);
Thread t2 = new Thread(myRunnable);
Thread t3 = new Thread(myRunnable);
t1.start();
t2.start();
t3.start();
结果(有群发那味了):
在第三种模型中,一条消息会被所有订阅的队列都消费。但是,在某些场景下,希望不同的消息被不同的队列消费。这时候就需要用直连交换机构建的路由routing模型了。
图解:
// 通过通道声明交换机
channel.exchangeDeclare("logs_routing", "direct");
// 发送消息
String routingKey = "info";
channel.basicPublish("logs_routing", routingKey, null, ("这是direct模型发布的基于route key:" + routingKey).getBytes());
// 通道声明交换机以及交换的类型
channel.exchangeDeclare("logs_routing", "direct");
// 创建一个临时队列
String queueName = channel.queueDeclare().getQueue();
// 基于route key 绑定队列和交换机
channel.queueBind(queueName, "logs_routing", "error");
主题交换机通过对消息的路由键和队列到交换机的绑定模式之间的匹配,将消息路由给一个或多个队列(注意这是消息给一个或多个队列,和直连交换机可不同,直连是路由键和队列同名,一个消息对应一个队列这种才是直连)。主题交换机经常用来实现各种分发/订阅模式及其变种。主题交换机通常用来实现消息的多播路由(与第三种模型的广播路由不同)。
主题交换机拥有非常广泛的用户案例。当一个问题涉及到那些想要有针对性的选择需要接收消息的多消费/多应用
的时候,主题交换机都可以被列入考虑范围。
主题交换机和直连交换机相比,都是可以根据 routingkey 把消息路由到不同的队列。只不过主题交换机可以让队列在绑定 routingkey 的时候使用通配符。这种模型 routingkey 一般都是由一个或者多个单词组成,多个单词之间以.
分割,例如:item.insert
通配符
* (star) can substitute for exactly one word. 匹配一个单词
# (hash) can substitute for zero or more words. 匹配一个或多个单词
如:
audit.# 匹配audit.irs.corporate 或者 audit.irs 等
audit.* 只能匹配audit.irs
// 声明交换机以及交换机类型
channel.exchangeDeclare("topics", "topic");
// 发布消息
String routeKey = "user.delete";
channel.basicPublish("topics", routeKey, null, ("这里是topic动态路由模型,route key:" + routeKey).getBytes());
// 生命交换机以及交换机类型
channel.exchangeDeclare("topics", "topic");
// 创建一个临时队列
String queueName = channel.queueDeclare().getQueue();
// 绑定队列和交换机 动态通配符形式 route key
channel.queueBind(queueName, "topics", "use.*");
案例结果