消息队列面试题

消息队列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的反馈,连接断开,那么这个消息会重新等待消费,但如果没有断开,该消息会一直被锁定处于队列中,如果积压的过多将会导致程序无法继续消费数据。

所以我们要确保进行消费的反馈,成功或失败

消费失败的可以把消息放到另一个队列里面,手动取出处理

消息持久化

消息持久化主要是将交换机、队列以及消息都设置为可持久化

posted @ 2023-02-02 10:34  星光闪闪  阅读(77)  评论(0)    收藏  举报