写点什么

【Spring Boot 7】RabbitMQ 基础知识总结 (1),java 开发面试宝典

用户头像
极客good
关注
发布于: 刚刚

==================


1、ConnectionFactory(连接管理器)




应用程序与 RabbitMQ 之间建立连接的管理器。


2、Channel(信道)




消息推送使用的通道。


3、RoutingKey(路由键)




用于把生产者的数据分配到交换器上。


4、Exchange(交换器)




用于接受、分配消息。


5、BindKey(绑定键)




用于把交换器的消息绑定到队列上


6、Queue(队列)




用于存储生产者的消息。


五、RabbitMQ 的适用场景


===============


1、异步处理




场景说明:用户注册后,需要发送注册邮件和注册短信。


传统的做法有两种,①串行的方式;②并行的方式;

(1)串行方式

将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个动作顺序完成后才返回给客户端。


这种方式的问题是发送注册邮件和发送注册短信不是必须的,它只是一个通知,而这种做法让客户端等待没有必要等待的东西,影响用户体验。


(2)并行方式

将注册信息写入数据库后,发送邮件的同时,发送短信,以上三种操作都完成后,返回给客户端,并行的方式能缩短处理的时间。



假设三种业务节点分别使用 50ms,串行方式就是 150ms,并行方式就是 100ms。


虽然并行已经缩短了处理时间,但是前面说过,邮件和短信不是必须的,没有必要让客户等待响应,应该是写入数据库就直接返回。

(3)?消息队列 RabbitMQ

引入消息队列后,用户的响应时间就等于写入数据库的时间+写入消息队列的时间(可以忽略不计),引入消息队列后,响应时间大幅度缩减。


2、应用解耦



(1)场景

双 11 是购物狂欢节,用户下单后,订单系统需要通知库存系统,传统的做法就是订单系统调用库存系统接口。


(2)缺点

由于订单系统和库存系统的高耦合,当库存系统出现故障时,订单就会失败。

(3)引入消息队列 RabbitMQ


订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。


库存系统:订阅下单的消息,获取下单消息,进行库操作。就算库存系统出现故障,消息队列也能保证订单消息的可靠传递,不会导致消息丢失。


3、流量削峰




流量削峰一般在秒杀活动中应用广泛


场景:秒杀活动,一般因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。

(1)作用

① 可以控制活动人数,超过此阈值的订单直接丢弃。一般秒杀就是这个原理。


② 可以缓解短时间内的高流量压垮应用(应用程序按照自己的最大处理能力获取订单)。


(2)用户的请求,服务器收到之后,首先写入消息队列,加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面。

(3)秒杀业务根据消息队列中的请求信息,再做后续处理。

六、springboot 集成 RabbitMQ


======================


Spring Boot 集成 RabbitMQ 非常简单,如果只是简单的使用配置非常少,Spring Boot 提供了 spring-boot-starter-amqp 项目对消息各种支持。?


1、pom.xml




<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-amqp</artifactId>


</dependency>


2、配置 RabbitMQ 的安装地址、端口以及账户信息




spring.application.name=Spring-boot-rabbitmq


spring.rabbitmq.host=192.168.0.86


spring.rabbitmq.port=5672


spring.rabbitmq.username=admin


spring.rabbitmq.password=123456


3、队列配置




@Configuration


public class RabbitConfig {


@Bean


public Queue Queue() {


return new Queue("hello");


}


}


4、发送者




rabbitTemplate 是 Spring Boot 提供的默认实现


@component


public class HelloSender {


@Autowired


private AmqpTemplate rabbitTemplate;


public void send() {


String context = "hello " + new Date();


System.out.println("Sender : " + context);


this.rabbitTemplate.convertAndSend("hello", context);


}


}


5、接收者




@Component


@RabbitListener(queues = "hello")


public class HelloReceiver {


@RabbitHandler


public void process(String hello) {


System.out.println("Receiver : " + hello);


}


}


6、测试




@RunWith(SpringRunner.class)


@SpringBootTest


public class RabbitMqHelloTest {


@Autowired


private HelloSender helloSender;


@Test


public void hello() throws Exception {


helloSender.send();


}


}


发送者和接收者的 queue name 必须一致,否则不能接收


七、多对多使用


=======


一个发送者,N 个接收者或者 N 个发送者和 N 个接收者会出现什么情况呢?


1、一对多发送




对上面的代码进行了小改造,接收端注册了两个 Receiver,Receiver1 和 Receiver2,发送端加入参数计数,接收端打印接收到的参数,下面是测试代码,发送一百条消息,来观察两个接收端的执行效果


@Test


public void oneToMany() throws Exception {


for (int i=0;i<100;i++){


neoSender.send(i);


}


}


结果如下:


Receiver 1: Spring boot neo queue ****** 11


Receiver 2: Spring boot neo queue ****** 12


Receiver 2: Spring boot neo queue ****** 14


Receiver 1: Spring boot neo queue ****** 13


Receiver 2: Spring boot neo queue ****** 15


Receiver 1: Spring boot neo queue ****** 16


Receiver 1: Spring boot neo queue ****** 18


Receiver 2: Spring boot neo queue ****** 17


Receiver 2: Spring boot neo queue ****** 19


Receiver 1: Spring boot neo queue ****** 20


根据返回结果得到以下结论


一个发送者,N 个接收者,经过测试会均匀的将消息发送到 N 个接收者中


2、多对多发送




复制了一份发送者,加入标记,在一百个循环中相互交替发送


@Test


public void manyToMany() throws Exception {


for (int i=0;i<100;i++){


neoSender.send(i);


neoSender2.send(i);


}


}


结果如下:


Receiver 1: Spring boot neo queue ****** 20


Receiver 2: Spring boot neo queue ****** 20


Receiver 1: Spring boot neo queue ****** 21


Receiver 2: Spring boot neo queue ****** 21


Receiver 1: Spring boot neo queue ****** 22


Receiver 2: Spring boot neo queue ****** 22


Receiver 1: Spring boot neo queue ****** 23


Receiver 2: Spring boot neo queue ****** 23


Receiver 1: Spring boot neo queue ****** 24


Receiver 2: Spring boot neo queue ****** 24


Receiver 1: Spring boot neo queue ****** 25


Receiver 2: Spring boot neo queue ****** 25


结论:和一对多一样,接收端仍然会均匀接收到消息。


八、高级使用


======


1、对象的支持




springboot 完美的支持对象的发送和接收,不需要额外的配置。


//发送者


public void send(User user) {


System.out.println("Sender object: " + user.toString());


this.rabbitTemplate.convertAndSend("object", user);


}


...


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


//接收者


@RabbitHandler


public void process(User user) {


System.out.println("Receiver object : " + user);


}


结果如下:


Sender object: User{name='neo', pass='123456'}


Receiver object : User{name='neo', pass='123456'}


2、Topic??Exchange




topic 是 RabbitMQ 中最灵活的一种方式,可以根据 routing_key 自由的绑定不同的队列


首先对 topic 规则配置,这里使用两个队列来测试


@Configuration


public class TopicRabbitConfig {


final static String message = "topic.message";


final static String messages = "topic.messages";


@Bean


public Queue queueMessage() {

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
【Spring Boot 7】RabbitMQ基础知识总结(1),java开发面试宝典