1.组成部分说明:
- Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue
- Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
- Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的
- Producer:消息生产者,即生产方客户端,生产方客户端将消息发送
- Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。
1.生产者发送消息流程:
1、生产者和Broker建立TCP连接。
2、生产者和Broker建立通道。
3、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
4、Exchange将消息转发到指定的Queue(队列)
2.消费者接收消息流程:
1、消费者和Broker建立TCP连接
2、消费者和Broker建立通道
3、消费者监听指定的Queue(队列)
4、当有消息到达Queue时Broker默认将消息推送给消费者。
5、消费者接收到消息。
6、ack回复
3、定义RabbitConfig配置类,配置Exchange、Queue、及绑定交换机。
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
//队列
public static final String RABBIT_QUEUE = "rabbit.queue";
//交换机
public static final String RABBIT_EXCHANGE = "rabbit.exchange";
//声明队列
/*
* new Queue(QUEUE_EMAIL,true,false,false)
* durable="true" 持久化 rabbitmq重启的时候不需要创建新的队列
* auto-delete 表示消息队列没有在使用时将被自动删除 默认是false
* exclusive 表示该消息队列是否只在当前connection生效,默认是false
*/
@Bean(RABBIT_QUEUE)
public Queue RABBIT_QUEUE() {
return new Queue(RABBIT_QUEUE);
}
//声明交换机
@Bean(RABBIT_EXCHANGE)
public Exchange RABBIT_EXCHANGE() {
//durable(true) 持久化,mq重启之后交换机还在
return ExchangeBuilder.fanoutExchange(RABBIT_EXCHANGE).durable(true).build();
}
//队列绑定交换机,指定routingKey
@Bean
public Binding RABBIT_EXCHANGE_QUEUE(@Qualifier(RABBIT_QUEUE) Queue queue, @Qualifier(RABBIT_EXCHANGE) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("rabbit").noargs();
}
}
4.生产者(mq-rabbitmq-producer)
/**
* 参数:
* 1、交换机名称
* 2、routingKey
* 3、消息内容
*/
rabbitTemplate.convertAndSend(RabbitmqConfig.RABBIT_EXCHANGE,"rabbit",message);
5.消费者(mq-rabbitmq-consumer)
@Component
public class RabbitMqListener {
@RabbitListener(queues = RabbitMqConfig.RABBIT_QUEUE)
public void listener(Object message){
//能够获取到rabbitmq队列中的信息
System.out.println(message);
}
}
2.消息模式之订阅模式
1、一个生产者多个消费者
2、每个消费者都有一个自己的队列
3、生产者没有将消息直接发送给队列,而是发送给exchange(交换机、转发器)
4、每个队列都需要绑定到交换机上
5、生产者发送的消息,经过交换机到达队列,实现一个消息被多个消费者消费
Exchange类型有以下几种:
Fanout:广播
将消息交给所有绑定到交换机的队列
//声明交换机
@Bean(RABBIT_EXCHANGE)
public Exchange RABBIT_EXCHANGE() {
//durable(true) 持久化,mq重启之后交换机还在
return ExchangeBuilder.fanoutExchange(GOODS_EXCHANGE).durable(true).build();
}
rabbitTemplate.convertAndSend(RabbitmqConfig.RABBIT_EXCHANGE,null,message);
Direct:定向
把消息交给符合指定routing key 的队列
@Bean(RABBIT_QUEUE1)
public Queue RABBIT_QUEUE1() {
return new Queue(GOODS_QUEUE1);
}
@Bean(RABBIT_QUEUE)
public Queue RABBIT_QUEUE() {
return new Queue(GOODS_QUEUE);
}
//声明交换机
@Bean(RABBIT_EXCHANGE)
public Exchange RABBIT_EXCHANGE() {
//durable(true) 持久化,mq重启之后交换机还在
//directExchange交换机类型:路由模型
return ExchangeBuilder.directExchange(GOODS_EXCHANGE).durable(true).build();
}
//队列绑定交换机,指定routingKey
@Bean
public Binding RABBIT_EXCHANGE_QUEUE(@Qualifier(RABBIT_QUEUE) Queue queue, @Qualifier(RABBIT_EXCHANGE) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("error").noargs();
}
//队列绑定交换机,指定routingKey1
@Bean
public Binding RABBIT_EXCHANGE_QUEUE1(@Qualifier(RABBIT_QUEUE1) Queue queue, @Qualifier(RABBIT_EXCHANGE) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("info、error、warning").noargs();
}
rabbitTemplate.convertAndSend(RabbitMq.RABBIT_EXCHANGE,"error",message);
Topic:通配符
把消息交给符合routing pattern(路由模式) 的队列
#:匹配一个或多个词
*:匹配不多不少恰好1个词
@Bean(RABBIT_QUEUE1)
public Queue RABBIT_QUEUE1() {
return new Queue(RABBIT_QUEUE1);
}
@Bean(RABBIT_QUEUE)
public Queue RABBIT_QUEUE() {
return new Queue(RABBIT_QUEUE);
}
//声明交换机
@Bean(RABBIT_EXCHANGE)
public Exchange RABBIT_EXCHANGE() {
//durable(true) 持久化,mq重启之后交换机还在
//topicExchange:通配符模型
return ExchangeBuilder.topicExchange(RABBIT_EXCHANGE).durable(true).build();
}
//队列绑定交换机,指定routingKey
@Bean
public Binding RABBIT_EXCHANGE_QUEUE(@Qualifier(RABBIT_QUEUE) Queue queue, @Qualifier(RABBIT_EXCHANGE) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("error").noargs();
}
//队列绑定交换机,指定routingKey1
@Bean
public Binding RABBIT_EXCHANGE_QUEUE1(@Qualifier(RABBIT_QUEUE1) Queue queue, @Qualifier(RABBIT_EXCHANGE) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("*.error").noargs();
}
rabbitTemplate.convertAndSend(RabbitMq.RABBIT_EXCHANGE,"error",message);
rabbitTemplate.convertAndSend(RabbitMq.RABBIT_EXCHANGE,"queue.error",message);
Header:
header模式与routing不同的地方在于,header模式取消routingkey,使用header中的 key/value(键值对)匹配队列。
Header模式不展开了,感兴趣可以参考这篇文章https://blog.csdn.net/zhu_tianwei/article/details/40923131