MQ的作用
- 异步,如快递。快递员→菜鸟驿站→客户。提高系统的响应速度和吞吐量。
- 解耦,如java引用别的语言的功能。提高系统稳定性和可拓展性;可以实现数据分发,生产者发送一个消息后,可以由多个消费者来处理。
- 削峰,如 长江涨水→三峡大坝。以稳定的系统资源对突发的流量冲击。
缺点:
- 系统可用性降低:一旦MQ宕机,整个业务都会产生影响。高可用
- 系统的复杂度提高:要保证消息不丢失,消息不会重复调用,保证消息顺序性
- 数据一致性
如何保证消息不丢失
哪些环节会造成消息丢失
怎么防止消息丢失
生产者发送消息不丢失
kafka:消息发送 + 回调
RocketMQ:1、消息发送 + 回调。 2、事务消息。(保证生产者发送消息和执行本地事务的原子性)
现实生活中5min内要完成支付,就可以用事务消息保证。
RabbitMQ:1、消息发送 + 回调
2、手动事务:channel.txSelect()开启事务,channel.txCommit()提交事务,channel.txRollback()回滚事务。这种方式channel会产生阻塞,吞吐量低。
3、Publisher Confirm。流程跟RocketMQ的事务消息基本一样。
MQ主从消息同步不丢失
RocketMQ
- 同步同步,异步同步
- 两阶段提交
RabbitMQ
- 普通集群:消息时分散存储的,节点之间不会主动进行消息同步,可能丢消息。
- 镜像集群:会在节点之间主动进行数据同步,这样数据安全性得到提高。
Kafka:通常都是用在允许消息少量丢失的场景(acks,0,1,all)
MQ消息存盘不丢失
RocketMQ:同步刷盘,异步刷盘:异步刷盘效率更高,但是可能丢消息。
RabbitMQ:将队列配置成持久化队列。新增的Quorum队列,采用Raft协议来进行消息同步。
MQ消费者消费信息不丢失
RocketMQ:使用默认方式就行,不采用异步方式。
RabbitMQ:autoCommit → 手动提交offset
Kafka:手动提交offset
如何保证消息的顺序
全局有序和局部有序:MQ只需要保证局部有序,不保证全局有序。
https://rocketmq.apache.org/docs/order-example/
对于一个队列来说总是有序的。
生产者把一组有序的消息放到同一个队列当中,而消费者一次消费整个队列当中的消息。
RocketMQ中有完整的设计,但是在RabbitMQ和Kafka当中需要自己设计。
RabbitMQ:要保证目标exchange只对应一个队列。并且一个队列只对应一个消费者。
Kafka:生产者通过定制partition分配规则,将消息分配到同一个partition,Topic下只对应一个消费者。
产品选择
Kafka
优点:吞吐量非常大,性能非常好,集群高可用。
缺点:会丢数据,功能单一。
使用场景:日志分析、大数据采集
RabbitMQ
优点:消息可靠性高,功能全面
缺点:吞吐量比较低,消息积累会严重影响性能,erlang语言不好定制。
使用场景:小规模场景。
RocketMQ
优点:高吞吐,高性能,高可以,功能非常全面。
缺点:开源版功能不如云上商业版,官方文档和周边生态不够成熟。客户端只支持java。
使用场景:几乎全场景。