MQ 面试大纲(持续更新)
2021-12-29 17:37:14 1 举报
AI智能生成
点我主页,涵盖 Java 后面面试所有知识点,本人持续整理,目前已帮助20+人拿到 大厂Offer
作者其他创作
大纲/内容
消息队列高手课
主题和队列有什么区别?
队列模型模型
实现者:RabbitMQ
增加 exchange ,让不同的消费者消费全量消息
发布-订阅模型
RocketMQ
增加 消费者组 让不同的消费者消费全量消息
每个主题下为什么有多个队列?
由于需要保证消息有序性,在server 未收到 client ack 之前,其他消费者不能消费这个队列,
Kafka
如何去报消息不丢失
生产阶段
存储阶段
消费阶段
消息挤压如何处理?
确保 Consumer 消费没有异常,死锁等
水平扩容增加 Consumer 的实例数量
如何保证消息不被重读消费?
消费端做好幂等
如何实现单个队列的并行消费?
增加一个重试队列
如何保证消息的严格顺序?
主题层面是无法保证严格顺序的,只有在队列上才能保证消息的严格顺序。
全局严格顺序
单个生产者,单个队列,单个消费者
局部严格顺序
在发送端,我们使用账户 ID 作为 Key,采用一致性哈希算法计算出队列编号,指定队列来发送消息。一致性哈希算法可以保证,相同 Key 的消息总是发送到同一个队列上,这样可以保证相同 Key 的消息是严格有序的。如果不考虑队列扩容,也可以用队列数量取模的简单方法来计算队列编号。
让你自己设计如何实现一个 MQ?
高性能异步网络
NIO,Netty
序列化与反序列化
传输协议
基于 TCP 协议封装自己的高效协议
内存管理
缓存
读写缓存
缓存置换策略
减少同步锁使用
CAS 无锁编程
分布式
rabbitMq
问: 为什么选择这个mq?
缺点:
理解 RabbitMQ Exchange
有几种exchange?
Fanout Exchange(所有)
Direct Exchange(默认)根据routingKey精确匹配
Topic Exchange 支持 routingKey 模糊匹配
rabbitMQ 为什么这么快?(得物)
1.基于内存
2. Erlang 语言编写
RabbitMQ 集群原理
如何保证消息队列的高可用啊?
单机模式
就是demo级别的,一般就是你本地启动了玩玩儿的,没人生产用单机模式
普通集群模式
提高吞吐量
持久化
消息挤压时,易扩展
镜像模式
每个节点都有完整的 queue 数据
优点
高可用
缺点
网络开销严重
当MQ消息挤压时扩展性不好
如何开启镜像模式,在 RabbitMQ 控制台
如何保证消息的可靠性传输(如何处理消息丢失的问题)?rabbitmq
消息丢失分为三个阶段:
在生产者丢失
生产者发送消息根本没有到达 mq server
解决: 开启生产者 confirm 机制
在 rabbitmq server 丢失
mq server 收到生产者发来的消息,立即挂掉
解决:开启消息持久化机制
必须:
1. 创建 Queue 的时候设置 queue 的持久化
2. 发送消息的时候设置 投递模式(deliveryMode) 为 2
1. 创建 Queue 的时候设置 queue 的持久化
2. 发送消息的时候设置 投递模式(deliveryMode) 为 2
在消费者丢失
mq server 把消息投递给消费者,消费者拿到消息没消费挂掉
解决:开启消费者 手动 ack 机制
注意: 消费者幂等
如何避免消息重复投递或重复消费?
生产者重复发送消息:
MQ内部针对每条生产者发送的消息生成一个inner-msg-id,
作为去重和幂等的依据(消息投递失败并重传),避免重复的消息进入队列
作为去重和幂等的依据(消息投递失败并重传),避免重复的消息进入队列
消费者重复消费消息:
消费者根据消息中的 bizId(业务 ID,订单号,诊次号等)作为去重和幂等判断依据
如何实现一个延迟队列?
死信队列
延迟插件
RocketMQ
问:为什么选择这个mq?
缺点:
kafka
问:为什么选择这个mq?
为什么在你们系统架构中要引入消息中间件?
复杂系统的解耦
复杂链路的异步调用
瞬时高峰的削峰处理
系统架构引入消息中间件有什么缺点?
系统可用性降低
系统稳定性降低
分布式一致性问题
如何保证消息的顺序性?
全局顺序
全局顺序 对于指定的一个 Topic,所有消息按照严格的先入先出(FIFO)的顺序进行发布和消费。 适用场景:性能要求不高,所有的消息严格按照 FIFO 原则进行消息发布和消费的场景
分区顺序
全局顺序 对于指定的一个 Topic,所有消息按照严格的先入先出(FIFO)的顺序进行发布和消费。 适用场景:性能要求不高,所有的消息严格按照 FIFO 原则进行消息发布和消费的场景
如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?
不要开启消息的过期失效
开启消息队列持久化
再部署一个MQ集群,把消息移到这里,开启消费线程进行数据消费
如何保证多个消费者只消费一次消息
Spring Cloud Stream 设置消费者组 group:
多个服务侦听同一个消息队列,只要这些实例同属于一个组,
Spring Cloud Stream和底层消息代理机制就会保证消息只被消费一次
多个服务侦听同一个消息队列,只要这些实例同属于一个组,
Spring Cloud Stream和底层消息代理机制就会保证消息只被消费一次
MQ 如何保证幂等性?
分两个阶段来讨论
上半场消息发送阶段:消息发送两次
MQ发送端,到MQ-server的幂等性(上半场);
由MQ保证
下半场消息消费阶段:消息接收两次
MQ-server,到MQ接收端的幂等性(下半场);
由业务方保证
MQ 发送端
MQ 能接受端
MQ Server
MQ 四种投递模式
Topic: 消息的发布是指某个生产者向某个topic发送消息;消息的订阅是指某个消费者关注了某个topic中带有某些tag的消息,进而从该topic消费数据。
Pub/Sub 模型
生产者将消息发送到 Topic 中,订阅了该 Topic 的所有下游消费者都会受到这条消息。1:n
PTP 模型
一个队列可以有多个生产者和消费者,队列中的每一条消息只能由一个消费者消费,消费之后就会从队列中移除。1:1
需要注意的是,在存在多个下游消费者的情况下,消息的消费并不是有序的。
为了保证消费的有序性,一些 MQ 提供了 “专有消费者”或者“排他消费者”的概念。这种情况下,同一时刻只能有一个消费者在处理消息。
“专有消费者” 的缺点就是失去的消息消费的并行性,消息很多的情况下,会产生消息积压。
为了解决 “专有消费者” 的性能问题,一些 MQ 又采用了分区的概念。
需要注意的是,在存在多个下游消费者的情况下,消息的消费并不是有序的。
为了保证消费的有序性,一些 MQ 提供了 “专有消费者”或者“排他消费者”的概念。这种情况下,同一时刻只能有一个消费者在处理消息。
“专有消费者” 的缺点就是失去的消息消费的并行性,消息很多的情况下,会产生消息积压。
为了解决 “专有消费者” 的性能问题,一些 MQ 又采用了分区的概念。
Partition 模型 (kafka,rocketmq)
生产者发送消息到某个 Topic,最终选择一个 partition 进行发送,每个 partition 存储可以存储一个订单的 创建,变更,完成的消息,然后由一个消费者消费,这样就保证了消息的有序性。多个 partition 又可以同时消费,解决了消费性能问题。但是 partition 数量有限。
对于 Partition 多了一个消费者组的概念:
一个 Partition 只能分配给一个消费者组。
一个消费者可以分配到多个 Partition。
一个消费者组可以有多个消费者。
每个消费者只能消费分配给自己 Partition 中的消息。
一个 Partition 只能分配给一个消费者组。
一个消费者可以分配到多个 Partition。
一个消费者组可以有多个消费者。
每个消费者只能消费分配给自己 Partition 中的消息。
Transfer 模型
为了解决 Partition 的数量有限问题
可靠消息一致性?
定义:是为了解决 Producter 端的消息发送与本地事物执行的原子性问题。
典型场景: 本地往 DB 插入一条数据,并发送 一条 MQ 消息。要保证这两个操作的原子性。
典型场景: 本地往 DB 插入一条数据,并发送 一条 MQ 消息。要保证这两个操作的原子性。
解决
1. 本地事务表
2. RocketMQ 事物消息
3. Binlog 订阅解析
binlog 应用场景
业务可以伪装成 mysql master 的 slave 节点,感知数据的变化
应用
1.数据异构
各个业务系统都关注同一份数据的变更,改为订阅 binlog 日志+MQ
2.基于数据的任务分发
当原始业务系统修改数据后,不需要和其它业务系统关联,由调度系统读取 binlog 进行任务分发。
3.缓存数据的补充
当客户端更改数据后,中间件系统通过 binlog 获得数据变更,并同步到缓存中。
这样就保证了缓存中数据的有效性。
这样就保证了缓存中数据的有效性。
4. 读写分离
binlog 订阅组件+MQ
阿里开源: canal
0 条评论
下一页