欢迎关注WX公众号:“程序猿补课班”,分享Java相关技术知识,学习经验,面试经验等。小伙伴快来补课吧!
正文开始
1.为什么要使用MQ?
解耦 系统耦合度降低,没有强依赖关系
异步 不需要同步执行的远程调用可以有效提高响应时间
削峰 请求达到峰值后,后端还可以保持固定消费速率消费,不会被压垮。
2.RocketMQ如何保证消息不丢失?
首先在如下三个部分都可能会出现丢失消息的情况:
Producer端:
采取send()同步发消息,发送结果是同步感知的。
发送失败后可以重试,设置重试次数。默认3次。
Broker端:
修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。
Consumer端:
完全消费正常后在进行手动ack确认。
3.RocketMQ的消息堆积如何处理?
首先要找到是什么原因导致的消息堆积,是Producer太多了,Consumer太少了导致的还是说其他情况,总之先定位问题。 然后看下消息消费速度是否正常,正常的话,可以通过上线更多consumer临时解决消息堆积问题。
4.如果Consumer和Queue不对等,上线了多台也在短时间内无法消费完堆积的消息怎么办?
- 准备一个临时的topic;
- queue的数量是堆积的N倍;
- queue分布到多台broker中
- 上线一台consumer做消息搬运工,把原来topic中的信息搬到新topic中,不做业务处理,只搬运
- 上线N台consumer同时消费topic中的数据
5.堆积时间过长消息超时了?
RocketMQ中的消息只会在commitLog被删除的时候才会消失,不会超时。也就是说未被消费的消息不会存在超时删除这情况。
6.堆积的消息会不会进死信队列?
不会,消息在消费失败后会进入重试队列,超过一定次数才会进入死信队列。
7.那么在什么时候会变成死信?
消息拒绝并且没有设置重新入队
消息过期
消息堆积,并且队列达到最大长度,先入队的消息会变成DL。
8.消息重复消费怎么处理?
出现原因
正常情况下在consumer真正消费完消息后应该发送ack,通知broker该消息已正常消费,从queue中剔除
当ack因为网络原因无法发送到broker,broker会认为词条消息没有被消费,此后会开启消息重投机制把消息再次投递到consumer。
消费模式:在CLUSTERING模式下,消息在broker中会保证相同group的consumer消费一次,但是针对不同group的consumer会推送多次
解决方案
- 数据库表:处理消息前,使用消息主键在表中带有约束的字段中insert
- Map:单机时可以使用map做限制,消费时查询当前消息id是不是已经存在
- Redis:使用分布式锁。
9.如何让RocketMQ保证消息的顺序消费?
首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue同时消费是无法绝对保证消息的有序性的。
可以使用同一topic,同一个QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线程去消费一个queue里的消息。
10.如果Broker宕了,NameServer是怎么感知到的?
Broker会定时(30s)向NameServer发送心跳
然后NameServer会定时(10s)运行一个任务,去检查一下各个Broker的最近一次心跳时间,如果某个Broker超过120s都没发送心跳了,那么就认为这个Broker已经挂掉了。
11.消费者获取消息有几种模式?
推送模式和拉取模式。
1. PushConsumer
推送模式(虽然 RocketMQ 使用的是长轮询)的消费者。消息的能及时被消费。使用非常简单,内部已处理如线程池消费、流控、负载均衡、异常处理等等的各种场景。
2. PullConsumer
拉取模式的消费者。应用主动控制拉取的时机,怎么拉取,怎么消费等。主动权更高。但要自己处理各种场景。
12.消费者消费模式有几种?
集群消费
消费者的一种消费模式。一个 Consumer Group 中的各个 Consumer 实例分摊去消费消息,即一条消息只会投递到一个 Consumer Group 下面的一个实例。
广播消费
消费者的一种消费模式。消息将对一 个Consumer Group 下的各个 Consumer 实例都投递一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。
如有错漏之处,敬请指正