一、MQ有什么用?有哪些具体的使用场景?
MQ:Message Queue 消息队列,队列是一种 FIFO 先进先出的数据结构,消息由生产者到 MQ 进行排队,然后由消费者对消息进行处理。QQ、微信 就是典型的 MQ 场景
MQ的作用主要有三个方面:
1、异步 异步能提高系统的响应速度和吞吐量
2、解耦 服务与服务之间进行解耦,可以减少服务之间的影响,提高系统的稳定性和可扩展性,另外,解耦之后可以实现数据分发,生产者发送一个消息后,可以由多个消费者处理
3、消峰 以稳定的系统资源对应突发的流量冲击
MQ 的缺点:
1、系统可用性降低 一旦 MQ 出现故障,整个业务就会产生影响
2、系统的复杂性提高 引入 MQ 后,数据链路就会变得很复杂
3、数据一致性问题 A系统发出消息,需要由 B、C 两个系统统一同时处理,如果 B 系统处理成功,C系统处理失败,就会造成数据一致性的问题
二、如何进行产品选型?
RocketMQ:
优点:高吞吐量,高性能,高可用,功能十分全面
缺点:开源版本功能不如云商业版;官方文档和周边生态不够成熟;客户端只支持JAVA
使用场景:几乎所有场景都适用
RabbitMQ:
优点:消息可靠性高,功能全面
缺点:吞吐量比较低,消息累积会严重影响性能;erlang 语言不便于定制开发
使用场景:小规模场景
kafka:
优点:吞吐量非常大,性能非常好,集群高可用
缺点:会丢数据,功能比较单一
使用场景:日志分析,大数据采集
三、如何保证消息不丢失?
1、哪些环节会造成消息丢失
2、怎样去防止消息丢失
2.1 生产者发送消息不丢失
RocketMQ:
1、消息发送 + 回调
2、事务消息(保证本地事务和发送消息的原子性)
RabbitMQ:
1、消息发送 + 回调
2、手动事务 channel.txSelect() 开启事务;channel.txCommit() 提交事务;channel.txRollback() 回滚事务
3、publish confirm 整个处理流程跟 RocketMQ 的事务消息基本是一样的
Kafka:
1、消息发送 + 回调
2.2 MQ主从消息不丢失
RocketMQ:
1、普通集群 同步同步;异步同步。异步同步效率更高,但是又丢失消息的风险;同步同步不会丢消息,但是又阻塞的风险
2、Dledger 集群 两阶段提交,集群为奇数(至少三台)
RabbitMQ:
1、普通集群 消息分散存储,节点之间不会主动进行消息同步,但有可能丢失消息
2、镜像集群 会在节点之间主动进行数据同步,这样数据安全性得到了有效保证
kafka:
1、允许消息少量丢失
2.3 MQ消息存盘不丢失
RocketMQ:同步刷盘;异步刷盘
RabbitMQ:将队列配置成持久化队列。3.x版本新增 Quorum 类型的队列,会采用 Raft 协议来进行消息同步
2.4 MQ消费者消费消息不丢失
RocketMQ:使用默认的方式消息就行,不要采用异步方式
RabbitMQ:autoCommit 关掉,改为手动提交 offset
kafka:手动提交 offset
四、如何保证消息消费的幂等性?
其实就是防止重复消费的问题,所有 MQ 产品都没有提供主动解决幂等性机制,需要由消费者自行控制
RocketMQ:给每个消息分配了 MessageID,这个 MessageID 就可以作为消费者判断幂等性的依据。这种方式不太建议,因为并不能保证MessageID唯一性。最好的方式就是自己带一个有业务表示的ID,来进行幂等操作,例如 订单ID
五、如何保证消息的顺序?
全局有序和局部有序:MQ 只需要保证局部有序,不需要保证全局有序。
生产者把一组有序的消息放到同一队列中,而消费者一次消费整个队列中的消息
RocketMQ: 有完整的解决方案,但在 RabbitMQ 和 kafka 中,没有完整的解决方案,需要自己设计
RabbitMQ :要保证目标 exchange 只对应一个队列,并且一个队列只对应一个消费者
kafka:生产者通过定制 partition 分配规则,将消息分配到同一个 partition,Topic 只对应一个消费者
六、如何保证消息的高效读写?
零拷贝:kafka 和 RocketMQ 都是通过零拷贝技术来优化文件读写。零拷贝分为:mmap 和 transfile
传统文件拷贝需要对文件进行四次拷贝操作;mmap 零拷贝在用户空间只需要创建该文件的基本属性即可,无需拷贝整改文件,在内核空间进行文件拷贝; transfile 文件在网卡层进行操作
RocketMQ 当中使用 mmap 方式来对它的文件进行拷贝
kafka 当中,它的 index 日志文件也是通过 mmap 的方式来拷贝文件的,其他的日志文件中,是通过 transfile 方式将硬盘数据加载到网卡
七、使用MQ如何保证分布式事务的最终一致性?
分布式事务:业务相关的多个操作,保证它们同时成功或者同时失败
最终一致性,与之对应的是强一致性
MQ 中要保证事务的最终一致性,就需要做到两点:
1、生产者要保证 100% 的消息投递 — 事务消极机制
2、消费者要保证幂等消费 — 唯一ID + 业务自己实现幂等操作