rocketmq 重复拉取消息_持续输出面试题之RocketMQ篇

开篇介绍

大家好,我是Java最全面试题库的提裤姐,今天这篇是中间件面试题系列的第二篇,主要总结了RocketMQ相关的面试题;在后续,会沿着第一篇开篇的知识线路一直总结下去,做到日更!如果我能做到百日百更,希望你也可以跟着百日百刷,一百天养成一个好习惯。

多个MQ如何选型?

RabbitMQ

erlang开发,对消息堆积的支持并不好,当大量消息积压的时候,会导致 RabbitMQ 的性能急剧下降。每秒钟可以处理几万到十几万条消息。

RocketMQ

java开发,面向互联网集群化,功能丰富,对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,每秒钟大概能处理几十万条消息。

Kafka

Scala开发,面向日志,功能丰富,性能最高。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。所以,Kafka 不太适合在线业务场景。

ActiveMQ

java开发,简单,稳定,性能不如前面三个。不推荐。

RocketMQ组成部分有哪些?

Nameserver

无状态,动态列表;这也是和zookeeper的重要区别之一。zookeeper是有状态的。

Producer

消息生产者,负责发消息到Broker。

Broker

就是MQ本身,负责收发消息、持久化消息等。

Consumer

消息消费者,负责从Broker上拉取消息进行消费,消费完进行ack。

RocketMQ消费模式有几种?

集群消费

一条消息只会被同Group中的一个Consumer消费

多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据

广播消费

消息将对一个Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。

消息重复消费如何解决?

出现原因

正常情况下在consumer真正消费完消息后应该发送ack,通知broker该消息已正常消费,从queue中剔除

当ack因为网络原因无法发送到broker,broker会认为词条消息没有被消费,此后会开启消息重投机制把消息再次投递到consumer。

消费模式:在CLUSTERING模式下,消息在broker中会保证相同group的consumer消费一次,但是针对不同group的consumer会推送多次

解决方案

数据库表:处理消息前,使用消息主键在表中带有约束的字段中insert

Map:单机时可以使用map做限制,消费时查询当前消息id是不是已经存在

Redis:使用分布式锁。

RocketMQ如何保证消息的顺序消费?

首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue同时消费是无法绝对保证消息的有序性的。

可以使用同一topic,同一个QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线程去消费一个queue里的消息。

RocketMQ如何保证消息不丢失?

Producer端

采取send()同步发消息,发送结果是同步感知的。

发送失败后可以重试,设置重试次数。默认3次。

Broker端

修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。

集群部署

Consumer端

完全消费正常后在进行手动ack确认

RocketMQ如何实现分布式事务?

1、生产者向MQ服务器发送half消息。

2、half消息发送成功后,MQ服务器返回确认消息给生产者。

3、生产者开始执行本地事务。

4、根据本地事务执行的结果(UNKNOW、commit、rollback)向MQ Server发送提交或回滚消息。

5、如果错过了(可能因为网络异常、生产者突然宕机等导致的异常情况)提交/回滚消息,则MQ服务器将向同一组中的每个生产者发送回查消息以获取事务状态。

6、回查生产者本地事物状态。

7、生产者根据本地事务状态发送提交/回滚消息。

8、MQ服务器将丢弃回滚的消息,但已提交(进行过二次确认的half消息)的消息将投递给消费者进行消费。

Half Message:预处理消息,当broker收到此类消息后,会存储到RMQ_SYS_TRANS_HALF_TOPIC的消息消费队列中

检查事务状态:Broker会开启一个定时任务,消费RMQ_SYS_TRANS_HALF_TOPIC队列中的消息,每次执行任务会向消息发送者确认事务执行状态(提交、回滚、未知),如果是未知,Broker会定时去回调在重新检查。

超时:如果超过回查次数,默认回滚消息。

也就是他并未真正进入Topic的queue,而是用了临时queue来放所谓的half message,等提交事务后才会真正的将half message转移到topic下的queue。

RocketMQ的消息堆积如何处理?

1、如果可以添加消费者解决,就添加消费者的数据量

2、如果出现了queue,但是消费者多的情况。可以使用准备一个临时的topic,同时创建一些queue,在临时创建一个消费者来把这些消息转移到topic中,让消费者消费。

你可能感兴趣的:(rocketmq,重复拉取消息)