rabbitmq工作模式详解之路由模式-routing
严格按照消息的路由将消息发送至对应的队列,监听器监听各自的队列消费消息,可以使用direct类型交换机,使用topic类型交换机也可以实现,我这里还是使用topic,因为它功能很强大
使用topic实现路由模式的时候要注意使用*和#通配符带来的风险,确保消息路由的准确性
package com.gitee.small.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TopicRabbitConfig {
//绑定键
public final static String DOG = "topic.dog";
public final static String CAT = "topic.cat";
/**
* Queue构造函数参数说明
* new Queue(SMS_QUEUE, true);
* 1. 队列名
* 2. 是否持久化 true:持久化 false:不持久化
*/
@Bean
public Queue firstQueue() {
return new Queue(TopicRabbitConfig.DOG);
}
@Bean
public Queue secondQueue() {
return new Queue(TopicRabbitConfig.CAT);
}
@Bean
public TopicExchange exchange() {
return new TopicExchange("topicExchange");
}
/**
* 将firstQueue和topicExchange绑定,而且绑定的键值为topic.dog
* 这样只要是消息携带的路由键是topic.dog,才会分发到该队列
*/
@Bean(name = "binding.dog")
public Binding bindingExchangeMessage() {
return BindingBuilder.bind(firstQueue()).to(exchange()).with(DOG);
}
/**
* 将secondQueue和topicExchange绑定,而且绑定的键值为用上通配路由键规则topic.cat
*/
@Bean(name = "binding.cat")
public Binding bindingExchangeMessage2() {
return BindingBuilder.bind(secondQueue()).to(exchange()).with(CAT);
}
}
由于我之前一直是在用同一个交换机和队列演示,所以在进行路由模式演示之前要先将topic.cat队列和topic.#路由解绑
手动解绑:登录rabbitmq客户端,到exchanges标签下根据virtual host和交换机名称找到对应交换机,再找到binging信息,点击unbind手动解绑
rabbitAdmin.removeBinding自动解绑:
RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitTemplate);
// 怎么绑定的就怎么解绑
rabbitAdmin.removeBinding(BindingBuilder.bind(new Queue("topic.cat"))
.to(new TopicExchange("topicExchange")).with("topic.#"));
消息发送直接选择rabbitTemplate即可
rabbitTemplate.convertAndSend("topicExchange", "topic.dog", "路由模式测试-dog");
rabbitTemplate.convertAndSend("topicExchange", "topic.cat", "路由模式测试-cat");
监听器示例
package com.gitee.small.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RoutingRabbitReceiver {
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.dog"),
exchange = @Exchange(value = "bindingExchangeMessage", type = ExchangeTypes.TOPIC)
))
public void process(String msg) {
log.info("dog-收到消息:{}", msg);
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.cat"),
exchange = @Exchange(value = "bindingExchangeMessage2", type = ExchangeTypes.TOPIC)
))
public void process2(String msg){
log.info("cat-收到消息:{}", msg);
}
}
结果示例
c.g.s.rabbitmq.RoutingRabbitReceiver : dog-收到消息:路由模式测试-dog
c.g.s.rabbitmq.RoutingRabbitReceiver : cat-收到消息:路由模式测试-cat