消息队列面试题
消息队列MQ
消息队列(MQ)概述
Message Queue
指消息队列,是应用程序与应用程序的通信方法
消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ
而部分数据库如Redis、Mysql以及phxsql也可实现消息队列的功能。
应用程序间通信方式:
Socket,http,rpc,mq等
消息队列的应用场景
应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;避免应用间的相互影响
异步处理:多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;
限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;
消息驱动的系统:系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理;
jms
jms是Java消息服务(Java Message Service),是java平台提供的一套消息服务技术规范
jms的两种模式
消息队列包括两种模式:
点对点模式(point to point, queue)
发布/订阅模式(publish/subscribe,topic)。
点对点模式
点对点模式下包括三个角色:
消息队列
发送者 (生产者)
接收者(消费者)

消息发送者生产消息发送到queue中,然后消息接收者从queue中取出并且消费消息。消息被消费以后,queue中不再有存储,所以消息接收者不可能消费到已经被消费的消息。
点对点模式特点:
每个消息只有一个接收者(Consumer)(即一旦被消费,消息就不再在消息队列中,可以有多个消费者监听,但一个消息只被一个消费者消费);
发送者和接收者间没有依赖性,发送者发送消息之后,不管有没有接收者在运行,都不会影响到发送者下次发送消息;
接收者在成功接收消息之后需向队列应答成功,以便消息队列删除当前接收的消息;
发布/订阅模式
发布/订阅模式下包括三个角色:
角色主题(Topic)
发布者(Publisher)
订阅者(Subscriber)

发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。
发布/订阅模式特点:
每个消息可以有多个订阅者;
发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。
为了消费消息,订阅者需要提前订阅该角色主题,并保持在线运行;
RabbitMQ
RabbitMQ遵循AMQP协议,RabbitMQ的broker由Exchange,Binding,queue组成,其中exchange和binding组成了消息的路由键;客户端Producer通过连接channel和server进行通信,Consumer从queue获取消息进行消费(长连接,queue有消息会推送到consumer端,consumer循环从输入流读取数据)。rabbitMQ以broker为中心;有消息的确认机制。
RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦
RabbitMQ是开源的可复用的企业消息系统
开发语言:Erlang – 面向并发的编程语言。
支持AMQP消息队列协议
解决的问题:商品数据同步(如:后台编辑商品信息后,前台系统要同步,搜索系统的索引库也要同步)
RabbitMQ特点
支持持久化
支持事务
amqp与jms区别
jms 只允许基于JAVA实现的消息平台的之间进行通信,amqp可以跨语言跨平台
jms支持点对点和发布/订阅两种消息模型,amqp支持多种消息模型
rabbitmq支持的消息模型
简单队列:
一个生产者,一个消费者
work模式队列
一个生产者,多个消费者
一个消息只能被一个消费者获得
可以进行平均分配消息,也可以能者多劳(争抢消息)

订阅模式队列
解读:
1、1个生产者,多个消费者
2、每一个消费者都有自己的一个队列
3、生产者没有将消息直接发送到队列,而是发送到了交换机
4、每个队列都要绑定到交换机
5、生产者发送的消息,经过交换机,到达队列,实现,一个消息被多个消费者获取的目的
这里生产者,不用声明队列,而是声明交换机,把消息发送给交换机,
消费者声明队列,并把队列绑定到交换机,监听队列,获得消息
注意:消息发送到没有队列绑定的交换机时,消息将丢失,因为,交换机没有存储消息的能力,消息只能存在在队列中。
交换机类型是fanout

路由模式队列
消费者可以有选择性地接收的消息
生产者定义交换机为路由类型,并在发送消息时指定key,消费者绑定交换机指定不同的key

交换机类型:direct
通配符模式队列
针对key可以用使用通配符,#可以匹配一个或多个词,*只能匹配一个词

交换机类型:topic
项目中应用
后台系统修改商品通过rabbitmq发消息(商品的id及修改类型)给前台系统,更新前台系统对商品的缓存
搜索系统:增,删,改都需要更新索引(solor中的)
项目中采用通配符模式队列
在service层进行发布消息
(
方案:
1、将Item对象做json序列化发送
a)数据大
b)有些数据其他人是可能用不到的
2、发送商品的id、操作类型
队列与交换机的绑定
实现:
1、在配置文件中将队列和交换机完成绑定
2、可以在管理界面中完成绑定
a)绑定关系如果发生变化,需要修改配置文件,并且服务需要重启
b)管理更加灵活
更容易对绑定关系的权限管理,流程管理
)
RabbitMQ的使用
安装erlang 安装rabbitmq-server
rabbitMQ默认的端口号是5672,管理界面的端口号是15672
spring对AMQP(MQ所遵循的协议)做了支持,并实现了对RabbitMQ的整合
导入spring与rabbitMQ的整合包
在spring的配置文件中配置(连接工厂,交换机,队列,RabbitMQ模板,做监听的Handler(controller)等)使用RabbitMQTemplate类来完成发布消息,监听的Handlern收到消息做出相应处理
(常用命令
1、服务器启动与关闭
启动:service rabbitmq-server start
关闭:service rabbitmq-server stop
重启:service rabbitmq-server restart
)
RabbitMQ消息安全机制
消息持久化:
可以设置持久化保证服务重启的情况下,也不会丢失消息
事务处理:
服务器已经接收到生产者的消息,但还没来得及持久化该消息时RabbitMQ服务器就断电了还是会丢失数据
这种小概率事件可以通过事务处理,保证消息的持久化不丢失数据
事务很少使用,性能很差
消费者确认机制(默认开启):
RabbitMQ把消息推送给Consumer,RabbitMQ就会把这个消息进行锁定,在锁定状态的消息不会被重复推送也就是二次消费。
其他consumer可以继续消费下一个消息,当消息的consumer确认消费完成之后发送一个ack给RabbitMQ,RabbitMQ会将这个消息删除。
如果生产者还没有收到consumer的反馈,连接断开,那么这个消息会重新等待消费,但如果没有断开,该消息会一直被锁定处于队列中,如果积压的过多将会导致程序无法继续消费数据。
所以我们要确保进行消费的反馈,成功或失败
消费失败的可以把消息放到另一个队列里面,手动取出处理
消息持久化
消息持久化主要是将交换机、队列以及消息都设置为可持久化

浙公网安备 33010602011771号