1. 为什么需要使用MQ消息中间件?
在实际开发中,有很多操作都是可以不同步执行的,比如邮件信息、短信的发送操作都不需要同步执行,还有一些服务的掉用也是可以不同步执行的,如果这一部分操作全都同步执行那么可能导致客户端阻塞的情况,并且会增加服务器的压力。而消息中间件就起到了一个,消息异步通知、流量削峰的作用。
2. 主流的MQ中间件有哪些?
ActiveMQ、RabbitMQ、Kafka等。
3. 如何在SpringBoot中使用RabbitMQ?
3.1 在项目中导入amqp启动器,并且编写rabbitMQ的相关连接配置信息
所需maven依赖
<!--引入rabbitmq所需依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
连接配置信息 application.yml
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
3.2 使用AmqpTemplate发送消息到指定队列(queue)中
@Autowired
private AmqpTemplate amqpTemplate;
@Test
public void testSendMsg(){
amqpTemplate.convertAndSend("myQueue",new Date());
}
3.3 使用@RabbitListener
注解监听队列中的消息
3.3.1 第一种方式:如果队列已经存在,那么就直接指定queue
//如果已经存在队列的情况下直接指定queue
@RabbitListener(queues = "myQueue")
public void process(String message){
log.info("amqp msg={}",message);
}
如果当前尚未创建队列,那么可以在rabbitmq的控制面板中创建一个
3.3.2 第二种方式:当前还不存在一个队列,需要程序在运行的时候创建
//2.目前不存在queue需要程序运行时自动创建
@RabbitListener(queuesToDeclare = @Queue("myQueue"))
public void process(String message){
log.info("amqp msg={}",message);
}
3.3.3 第三种方式:不存在队列,需程序创建一个,并且给队列指定路由
-
为什么要指定路由?
在实际开发中,有这样的情况,比如我们的消息提醒业务种类是不只一种的,比如有短信提醒、邮件提醒、微信模板消息等,但是他们的类型又是一样的,即他们都是一个消息。这个时候路由就是用来区分消息转发的路径。
从上图可以非常清晰的看出消息发送到RabbitMQ时的一个处理流程,想通过指定的队列名称找到相关队列,然后通过路由名称找到指定的转发路径。 -
编码实现消息发送端
@Autowired
private AmqpTemplate amqpTemplate;
@Test
public void testSendMsg(){
amqpTemplate.convertAndSend("sms","smsMsg",new Date()+"sms");
amqpTemplate.convertAndSend("wechatMsg","wechatMsg",new Date()+"wechatMsg");
}
- 消息接收端
@Slf4j
@Component
public class MqReceiver {
//1.如果已经存在队列的情况下直接指定queue
//@RabbitListener(queues = "myQueue")
//2.目前不存在queue需要程序运行时自动创建
//@RabbitListener(queuesToDeclare = @Queue("myQueue"))
//3.创建queue并指定路由,其中key是routerKey
@RabbitListener(bindings = @QueueBinding(
value = @Queue("myMsgQueue"),
key = "smsMsg",
exchange = @Exchange("sms")
))
public void processSms(String message){
log.info("amqp msg={}",message);
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue("myMsgQueue"),
key = "emailMsg",
exchange = @Exchange("email")
))
public void processEmail(String message){
log.info("amqp msg={}",message);
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue("myMsgQueue"),
key = "wechatMsg",
exchange = @Exchange("wechatMsg")
))
public void processWechatMsg(String message){
log.info("amqp msg={}",message);
}
}