RabbitMQ几种模式
一、普通模式(一个发送一个接收)
配置类
@Configuration
public class RabbitMQConfigFanout {
public static final String TEST_QUEUE = "test_queue";
/**
* Bean注解放到方法上,1、自动执行当前方法,将方法返回值放到ioc容器中
* 2、方法中有参数会在ioc容器中寻找同类型的参数注入到方法中
* <p>
* 生成消息队列queue
*
* @return
*/
@Bean
public Queue queue() {
return new Queue(TEST_QUEUE, true);
}
}
发送、接收方法
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 测试发送消息
*
* @param msg
*/
public void send(Object msg) {
log.info("发送消息:" + msg);
rabbitTemplate.convertAndSend(RabbitMQConfigFanout.TEST_QUEUE, msg);
}
/**
* 测试接收queue队列消息
*/
@RabbitListener(queues = RabbitMQConfigFanout.TEST_QUEUE)
public void receive(Object msg) {
log.info("接收消息:" + msg);
}
二、fanout(路由模式)
发送这发送消息给exchange,exchange再发送给所有接收者。所有接收者都能接收。
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfigFanout {
public static final String FANOUT_QUEUE01 = "fanout_queue01";
public static final String FANOUT_QUEUE02 = "fanout_queue02";
public static final String FANOUT_EXCHANGE = "fanout_exchange";
/**
* 测试路由模式
* 生成消息队列queue_fanout01
*
* @return
*/
@Bean
public Queue queue01() {
return new Queue(FANOUT_QUEUE01);
}
/**
* 测试路由模式
* 生成消息队列queue_fanout02
*
* @return
*/
@Bean
public Queue queue02() {
return new Queue(FANOUT_QUEUE02);
}
/**
* 测试路由模式
* 生成交换机
*
* @return
*/
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange(FANOUT_EXCHANGE);
}
/**
* 绑定交换机,将queue_fanout01与fanout_exchange绑定
*
* @return
*/
@Bean
public Binding binding01() {
return BindingBuilder.bind(queue01()).to(fanoutExchange());
}
/**
* 绑定交换机,将queue_fanout02与fanout_exchange绑定
*
* @return
*/
@Bean
public Binding binding02() {
return BindingBuilder.bind(queue02()).to(fanoutExchange());
}
}
发送、接收方法
/**
* 测试发送消息
* 向fanout_exchange交换机发送消息
*
* @param msg
*/
public void sendFanOut(String msg) {
log.info("fanOut发送消息:" + msg);
rabbitTemplate.convertAndSend(RabbitMQConfigFanout.FANOUT_EXCHANGE, "", msg);
}
/**
* 测试接收queue_fanout01消息
* 在路由模式下
*/
@RabbitListener(queues = RabbitMQConfigFanout.FANOUT_QUEUE01)
public void receiveFanout01(Object msg) {
log.info("接收queue_fanout01队列消息:" + msg);
}
@RabbitListener(queues = RabbitMQConfigFanout.FANOUT_QUEUE02)
public void receiveFanout02(Object msg) {
log.info("接收queue_fanout02队列消息:" + msg);
}
三、direct方法
- 发送消息给exchange时带上routingKey,指明接收者
- 与routingKey相匹配者接收消息
配置
@Configuration
public class RabbitMQConfigDirect {
public static final String QUEUE_DIRECT01 = "queue_direct01";
public static final String QUEUE_DIRECT02 = "queue_direct02";
public static final String DIRECT_EXCHANGE = "direct_exchange";
public static final String ROUTING_KEY01 = "queue.red";
public static final String ROUTING_KEY02 = "queue.green";
@Bean
public Queue queueDirect01() {
return new Queue(QUEUE_DIRECT01);
}
@Bean
public Queue queueDirect02() {
return new Queue(QUEUE_DIRECT02);
}
@Bean
public DirectExchange directExchange() {
return new DirectExchange(DIRECT_EXCHANGE);
}
@Bean
public Binding bindingDirect01() {
return BindingBuilder.bind(queueDirect01()).to(directExchange()).with(ROUTING_KEY01);
}
@Bean
public Binding bindingDirect02() {
return BindingBuilder.bind(queueDirect02()).to(directExchange()).with(ROUTING_KEY02);
}
}
发送、接收方法
/**
* direct模式下向ROUTING_KEY01测试发送消息
*
* @param msg
*/
public void sendDirect01(Object msg) {
log.info("direct模式下向发送" + RabbitMQConfigDirect.ROUTING_KEY01 + "消息:" + msg);
rabbitTemplate.convertAndSend(RabbitMQConfigDirect.DIRECT_EXCHANGE, RabbitMQConfigDirect.ROUTING_KEY01, msg);
}
public void sendDirect02(Object msg) {
log.info("direct模式下向发送" + RabbitMQConfigDirect.ROUTING_KEY02 + "消息:" + msg);
rabbitTemplate.convertAndSend(RabbitMQConfigDirect.DIRECT_EXCHANGE, RabbitMQConfigDirect.ROUTING_KEY02, msg);
}
/**
* 测试direct模式下接收消息
*/
@RabbitListener(queues = RabbitMQConfigDirect.QUEUE_DIRECT01)
public void receiveDirect01(Object msg) {
log.info("direct模式下接收" + RabbitMQConfigDirect.ROUTING_KEY01 + "消息:" + msg);
}
@RabbitListener(queues = RabbitMQConfigDirect.QUEUE_DIRECT02)
public void receiveDirect02(Object msg) throws InterruptedException {
// Thread.sleep(10000);
log.info("direct模式下接收" + RabbitMQConfigDirect.ROUTING_KEY02 + "消息:" + msg);
}
四、topic方式
*
匹配一个单词#
匹配0个或多个单词- 根据匹配规则接收消息(一个消息可能被多个接收)
- 绑定使用
BindingBuilder.bind(queueTopic02()).to(topicExchange()).with(ROUTING_KEY02);
@Configuration
public class RabbitMQConfigTopic {
public static final String TOPIC_QUEUE01 = "topic_queue01";
public static final String TOPIC_QUEUE02 = "topic_queue02";
public static final String TOPIC_EXCHANGE = "topic_exchange";
// * 匹配一个单词,# 匹配0个或多个单词
public static final String ROUTING_KEY01 = "queue.topic.*";
public static final String ROUTING_KEY02 = "queue.topic.#.test";
@Bean
public Queue queueTopic01() {
return new Queue(TOPIC_QUEUE01);
}
@Bean
public Queue queueTopic02() {
return new Queue(TOPIC_QUEUE02);
}
@Bean
public TopicExchange topicExchange() {
return new TopicExchange(TOPIC_EXCHANGE);
}
@Bean
public Binding topicBinding01() {
return BindingBuilder.bind(queueTopic01()).to(topicExchange()).with(ROUTING_KEY01);
}
@Bean
public Binding topicBinding02() {
return BindingBuilder.bind(queueTopic02()).to(topicExchange()).with(ROUTING_KEY02);
}
}
发送、接收方法
/**
* topic模式下发送消息,指定模糊匹配,匹配不同的routing key
*
* @param msg
*/
public void sendTopic01(Object msg) {
log.info("topic模式下向 queue.topic.test 发送消息:" + msg);
rabbitTemplate.convertAndSend(RabbitMQConfigTopic.TOPIC_EXCHANGE, "queue.topic.test", msg);
}
public void sendTopic02(Object msg) {
log.info("topic模式下向 queue.topic.test.test 发送消息:" + msg);
rabbitTemplate.convertAndSend(RabbitMQConfigTopic.TOPIC_EXCHANGE, "queue.topic.test.test", msg);
}
/**
* 测试topic模式下接收消息
*/
@RabbitListener(queues = RabbitMQConfigTopic.TOPIC_QUEUE01)
public void receiveTopic01(Object msg) {
log.info("topic模式下接收" + RabbitMQConfigTopic.ROUTING_KEY01 + "消息:" + msg);
}
@RabbitListener(queues = RabbitMQConfigTopic.TOPIC_QUEUE02)
public void receiveTopic02(Object msg) {
log.info("topic模式下接收" + RabbitMQConfigTopic.ROUTING_KEY02 + "消息:" + msg);
}
五、header方式
- 配置绑定exchange时带上map,使用whereAll、whereAny进行匹配,前者匹配所有map,后者匹配一个即可接收消息
- 发送消息时带上Message,在MessageProperties中设置header值
@Configuration
public class RabbitMQConfigHeader {
public static final String QUEUE_HEADER01 = "queue_header01";
public static final String QUEUE_HEADER02 = "queue_header02";
public static final String HEADER_EXCHANGE = "queue_exchange";
@Bean
public Queue queueHeader01() {
return new Queue(QUEUE_HEADER01);
}
@Bean
public Queue queueHeader02() {
return new Queue(QUEUE_HEADER02);
}
@Bean
public HeadersExchange headersExchange() {
return new HeadersExchange(HEADER_EXCHANGE);
}
@Bean
public Binding headerBinding01() {
Map<String, Object> map = new HashMap<>();
map.put("color", "red");
map.put("speed", "low");
return BindingBuilder.bind(queueHeader01()).to(headersExchange()).whereAll(map).match();
}
@Bean
public Binding headerBinding02() {
Map<String, Object> map = new HashMap<>();
map.put("color", "red");
map.put("speed", "high");
return BindingBuilder.bind(queueHeader02()).to(headersExchange()).whereAny(map).match();
}
}
发送、接收消息
/**
* header模式下发送消息测试
*
* @param msg
*/
public void sendHeader01(String msg) {
log.info("header模式下向" + RabbitMQConfigHeader.QUEUE_HEADER01 + "发送消息:" + msg);
MessageProperties messageProperties = new MessageProperties();
messageProperties.setHeader("color", "red");
messageProperties.setHeader("speed", "low");
Message message = new Message(msg.getBytes(), messageProperties);
rabbitTemplate.send(RabbitMQConfigHeader.HEADER_EXCHANGE, "", message);
}
public void sendHeader02(String msg) {
log.info("header模式下向" + RabbitMQConfigHeader.QUEUE_HEADER02 + "发送消息:" + msg);
MessageProperties messageProperties = new MessageProperties();
messageProperties.setHeader("color", "red");
messageProperties.setHeader("speed", "high");
Message message = new Message(msg.getBytes(), messageProperties);
rabbitTemplate.send(RabbitMQConfigHeader.HEADER_EXCHANGE, "", message);
}