MQ全称为Message Queue,即消息队列,是在传输消息的过程中保存消息的容器,是一个中间件,将应用程序进行解耦合,提升系统的容错性和可维护性,RabbitMQ是常见的MQ产品之一。
RabbitMQ的简单模式:
其中,P表示生产者 就是要发送消息的一方
C:消费者,接收消息,等待消息
中间部分queue表示消息队列,可以缓存消息,生产者向其中投递消息,消费者获取消息。
RabbitMQ的订阅模式:
订阅模式中多了一个exchange交换机角色,P生产者不在将消息直接发送到队列中,而是将消息发送给交换机,消息到交换机时,交换机转发到哪个队列需要根据路由键routing key来决定,exchange交换机一方面接收生产者发送来的消息,一方面知道如何处理消息,例如将消息递交给某个队列,或丢弃消息,且exchange只负责转发消息,并不具备存储信息的能力,到底怎样操作取决于exchange的类型,常见exchange类型有以下三种:
Fanout:广播,将消息交给所有绑定到交换机的队列
Direct:定向,将消息交给符合指定routing key的队列
Topic:通配符,将消息交给符合路由模式的队列
Direct Exchange:是默认交换模式,根据key匹配寻找队列
Topic Exchange:根据通配符转发消息,队列和交换机绑定会定义一种路由模式,可以根据路由模式和 routing key 把消息路由到不同的队列。
(routing key路由键必须是字符,用(.)隔开,例如item.insert
路由模式必须包含一个(#匹配一个或多个词)或(*匹配一个词)用于和路由键匹配,例如item.#匹配item.insert.abc,item.*匹配item.insert。)
Fanout Exchange:消息广播模式,会把消息发给绑定它的全部队列,配置了routing key也会被忽略。
SpringBoot整合RabbitMQ
在SpringBoot开发中,生产者工程中:
1.application.yml文件配置RabbitMQ相关信息;
2. 在生产者工程中编写配置类,用于创建交换机和队列,并进行绑定
3. 注入RabbitTemplate对象,通过RabbitTemplate对象发送消息到交换机
在SpringBoot开发中,消费者工程中:
1.application.yml文件配置RabbitMQ相关信息
4. 创建消息处理类,用于接收队列中的消息并进行处理
创建工程,添加依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
</dependencies>
启动类
@SpringBootApplication
public class ProducerApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerApplication.class);
}
}
创建application.yml
spring:
rabbitmq:
host: 192.168.194.128
port: 5672
virtual-host: /xzk
username: zhang
password: zhang
绑定交换机和队列
@Configuration
public class RabbitMQConfig {
// 交换机名称
public static final String ITEM_TOPIC_EXCHANGE="springboot_item_topic_exchange";
// 队列名称
public static final String ITEM_QUEUE="springboot_item_queue";
// 声明交换机
@Bean("itemTopicExchange")
public Exchange topicExchange(){
return ExchangeBuilder.topicExchange(ITEM_TOPIC_EXCHANGE).durable(true).build();
}
// 声明队列
@Bean("itemQueue")
public Queue itemQueue(){
return QueueBuilder.durable(ITEM_QUEUE).build();
}
// 绑定队列 交换机
@Bean
public Binding itemQueueExchange(@Qualifier("itemQueue") Queue queue,
@Qualifier("itemTopicExchange") Exchange
exchange){
return BindingBuilder.bind(queue).to(exchange).with("item.#").noargs();
}
运行生产者
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerTest {
@Resource
private RabbitTemplate rabbitTemplate;
@Test
public void testQueue(){
rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE,
"item.insert", "商品新增,routing key 为item.insert");
rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE,
"item.update", "商品修改,routing key 为item.update");
rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE,
"item.delete", "商品删除,routing key 为item.delete");
}
}
创建消费者工程
添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
启动类
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class);
}
}
application.yml
spring:
rabbitmq:
host: 192.168.194.128
port: 5672
virtual-host: /xzk
username: zhang
password: zhang
消息监听处理类
@Component
public class MyLinstener {
@RabbitListener(queues = "springboot_item_queue")
public void myListener(String message){
System.out.println("消费者接收");
}
}