作者:雨的到来2009 | 来源:互联网 | 2023-09-25 12:32
MQ 选型考量维度
可靠性、性能、功能、可运维性,可扩展性、是否开源及社区活跃
主题和队列
队列 和 发布-订阅模型
每个主题包含多个消息队列,通过多个消息队列实现并行生产和消费,
例如 RocketMQ 只在队列上保证消息的有序性,主题层面无法保证消息的严格顺序
队列 与主题 并没有本质的区别,他们最大的区别就是,一份消息能不能被多次消费。
如何利用事务性消息实现分布式事务
消息队列中的`事务`,主要解决的就是消息生产者和消息消费者的数据一致性问题。
例: RocketMQ 事务消息功能实现分布式事务流程如下
RocketMQ 中有事务反查机制,这种机制通过定时反查事务状态来补偿提交事务消息可能出现的失败。而在kafka中并没有这种反查机制(处理方式 直接抛异常),需要用户去自己解决这种问题
RocketMQ 的事务并没有完整实现事务的ACID (原子性、一致性、隔离性、持久性)四个特性
如何确保消息不会丢失
目前消息队列都提供了非常完善的消息可靠性保护机制,完全可以做到在消息传递过长中,及时发生网络中端或者硬件故障,也能保证消息的可靠性传递,不丢消息
检测消息丢失的方法
在消息生产者端,给每个消息附加一个连续递增的序号,然后在消息消费端检查(一般都有拦截器机制,不会侵入代码)这个序号的连续性。若检测到不连续的消息,则可通过缺失的序号判断丢了哪个消息。注意Kafka 和RocketMQ并不能保证 topic 上的严格顺序,so要指定分区(队列)
-
确保消息的可靠投递
-
生产阶段:在这个阶段,从消息在Producer 创建出来,经过网络传输发送到Broker端
-
存储阶段:在这个阶段,消息在Broker端存储,如果是集群,消息会在这个阶段被复制到其他的副本上
-
消费阶段:在这个阶段,Consumer从Broker 上拉取消息,经过网络传输发送到Cunsumer上
如何处理消费过程中的重复消息
消息重复的情况是必然的。在MQTT协议中,给处理三种传递消息的服务质量标准。从低到高依次是:
-
At most once :至多一次,在消息传递过程中,对多会被送达一次。也就是说,没什么消息可靠性保证,允许丢消息。使用场景如对可靠性不高的监控,允许少量数据丢失
-
At least once :至少一次,在消息传递时,至少会被送达一次,也就是说,不允许丢消息,但是允许有少量的重复消息出现 (大多数都是实现了它)
-
Exactly once:恰好一次,消息传递时,只会被送达一次,不允许也丢失不允许重复,这个是***的。
用幂等性解决重复消息问题
-
利用数据库唯一约束实现幂等
-
利用状态机、version 来实现幂等
-
记录并检查操作(适用范围广) : 如何check ? 可能会引入更多的问题。。。
消息积压了该如何处理
一般来说 是 : 要么生产变快了,要么消费变慢了
消费端是否可以通过批量消费的方式来提升消费性能?
1. 要求消费端能够处理或者开启多线程进行单条处理
2.批量消费一单某条数据消费失败会导致整批数据重复消费
3.对实时性要求不高,批量消费需要Broker积累到一定数据才会发送到Consumer,会使单次消费消息的耗时变长