RabbitMq面经

RabbitMq

1、请你说下RabbitMq的优缺点

答:优点:
	1、解耦 
	2、异步:减少请求的等待
    3、削峰限流:将所有的请求都写道消息队列中,按服务器能处理的请求消费
	缺点:
	1、系统的可用性降低:系统引用的外部依赖越多,月可能出问题,可能会造成雪崩
	2、系统的复杂度提高:加入消息对列后需要保证消息没有重复消费,以及如何处理消息丢失的问题
	3、数据一致性的问题:若BCD三个系统,BD系统写入成功,C系统写库失败,导致数据不一致性

2、RabbitMq的组成部分以及流程有哪些?

答:组成部分
	1、Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue
	2、Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过滤
	3、Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方
	4、producer:消息生产者,即生产方客户端,生产方客户端将消息发送到Mq
	5、Comuser:消息消费者,即消息方客户端,接受Mq转发的请求
   流程:
	发送消息:
		1、生产者与broker建立tcp连接
		2、生产者与broker建立通道
		3、生产者通过通道将消息发送给broker,由Exchange将消息转发
		4、Exchange将消息转发到指定的queue
	接收消息:
		1、消费者和broker建立tcp连接
		2、消费者和broker建立通道
		3、消费者监听指定的通道
		4、当有消息到达queue时Broker默认将消息推送给消费者
		5、消费者接收消息

3、RabbitMq有哪些工作模式?

答:
	1、work Queues(工作队列):多个消费者重复消费一个队列中的消息
	2、Publish/Subscribe 发布订阅:工作队列的进阶版,增加了交换机,可以有多个队列
	3、Routing 路由:每个队列可以设置一个或多个Routingkey,交换机根据路由请求转发
	4、topics 通配符:与routing类似,但不同的是topics使用的是通配符匹配,其中*匹配一个单词,#匹配多个或者0个单词
	5、Heander header转发器:header取消了routingkey,使用header中的key/value匹配对列
	6、RPC 远程过程调用:客户端远程调用服务端

4、如何保证消息不被重复消费

答:造成重复消费的原因:由于网络的故障,消费者消费完消息后,给消息队列发送的
确认码并没有传到消息队列中,导致消息队列不知道该消息已经消费过了,将消息在此发送给其他消费者。
	解决办法:
		1、改造业务逻辑,使得在重复消费时也不影响最终的结果,例如,通过版本号控制,对比消息队列中的版本号和数据库中的版本号
		2、基于数据库的唯一主键进行约束,消费完数据,insert一条数据,如果重复消费主键冲突,避免脏数据
		3、通过记录关键的key,当重复过来时,先判断当前key是否已经消费了

5、如何保证消息不丢失,进行可靠性传输?

答:
	1、生产者丢失数据:RabbitMq提供事务机制和确认机制两种模式确保生产者不丢消息
		1)、事务机制:若出现异常怎事务回滚,发送成功则提交数据,缺点发送消息时同步阻塞等待发送结果,造成吞吐量下降
		2)、确认机制:生产者将通道channel设置成confirm模式,每条消息被
		生成唯一的id,若发送成功,会发送个确认给生产者,若失败,也会发送一
		个Nack给生产者。Confirm模式最大的好处在于它是异步的,一旦发布消
		息,生产者就可以在等信道返回确认的同时继续发送下一条消息,当消息最
		终得到确认之后,生产者便可以通过回调方法来处理该确认消息。
	2、消息队列丢失数据:处理消息队列丢数据的情况,一般是开启持久化磁盘。持
	久化配置可以和生产者的 confirm 机制配合使用,在消息持久化磁盘后,再给
	生产者发送一个Ack信号。这样的话,如果消息持久化磁盘之前,即使
	rabbitMQ挂掉了,生产者也会因为收不到Ack信号而再次重发消息。
	3、消费者丢失数据:将自动确认信息更改为手动确认信息

6、如何处理消息堆积的情况?

  • 答:如几千万条数据在MQ里积压了七八个小时。
    	原因分析:消息堆积往往是生产者的生产速度与消费者的消费速度不匹配导致的。
    	有可能就是消费者消费能力弱,渐渐地消息就积压了,也有可能是因为消息消费失
    	败反复复重试造成的,也有可能是消费端出了问题,导致不消费了或者消费极其
    	慢。若是有bug则处理bug。
    	解决方法:
    		1)、临时扩容,快速处理积压的消息:
    			1、先修复comuser的问题,确保其恢复消费速度,然后将现有的comsumer都停掉
    			2、临时扩建原先N倍数量的queue,然后写一个临时分发数据的消
    			费者程序,将该程序部署上去消费队列中积压的数据,消费之后不
    			做任何耗时处理,直接均匀轮询写入临时建立好的 N 倍数量的 
    			queue 中;
    			3、临时征用 N 倍的机器来部署 consumer,每个 consumer 消费一个临时 queue 的数据
    			4、等快速消费完积压数据之后,恢复原先部署架构 ,重新用原先
    			的consumer 机器消费消息。这种做法相当于临时将 queue 资
    			源和 consumer 资源扩大 N 倍,以正常 N 倍速度消费。
    		2)、恢复队列中丢失的数据:若使用RabbitMq,并且设置了过期时间,当超过一定时间,数据就会被清理掉,导致数据的丢失。
    		可以采用批量重导的方式,在流量低峰期,写个程序手动查询丢失的那部分,并将消息冲新送入mq中。
    		3)、mq长时间未处理导致Mq写满的情况:这种是由于消息积压mq,扩建执行太慢
    		了,只好使用“丢弃+重新导入的方案”,写一个程序,连接mq里消费消息,消费一
    		个,丢弃一个,等在流量低峰期在重新查询导入。
    

7、如何保证RabbitMq的高可用?

答:单机模式、普通集群模式、镜像集群模式(不了解)

8、交换机无法根据自身的类型和路由键找到复合的条件队列时的处理方法?

答:设置mandatory=true,代表返回消息给生产者,设置mandatory=false,代表直接丢弃

9、消费者得到消息队列数据的方式?

答:push(服务端直接推送给客户端)和pull(客户端主动拉取消息)

10、消息基于什么传输的?

答:由于 TCP 连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶
颈。所以RabbitMQ 使用信道 channel 的方式来传输数据,信道是建立在真实的 
TCP 连接内的虚拟连接,且每条 TCP 连接上的信道数量没有限制。

11、死信队列DLX

答DLX也是一个正常的Exchange,和一般的Exchange没有任何区别。能在任何的队列上被指定,实际上就是设置某个队列的属性。当这个队列出现死信(dead message,就是没有任何消费者消费)的时候,RabbitMQ就会自动将这条消息重新发布到Exchange上去,进而被路由到另一个队列。可以监听这个队列中的消息作相应的处理。
消息变为死信的几种情况:消息被拒绝,同时requeue=false(不能重回队列)、TTL过期、队列达到最大长度,无法添加

12、延迟队列

答:存储对应的延迟信息,当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

13、优先级队列

答:优先级高的队列会先被消费,可以通过x-max-priority参数来实现。但是当消费速度大于生产速度且 Broker 没有堆积的情况下,优先级显得没有意义

你可能感兴趣的:(队列,交换机,rabbitmq,java,面试)