MQ消息有序性保证
想实现消息有序,需要从 Producer 和 Consumer 两方面来考虑
- Producer 生产消息时就必须要有序
- Consumer 消费消息时,也要按顺序来
[ 参考资料 ] : https://zhuanlan.zhihu.com/p/372469047
Producer生产者有序
像 RabbitMQ 这类普通的消息系统,队列结构简单,Producer 向队列中发送消息就完了,进入队列的消息肯定是有序的。
Kafka 比较特殊,因为它的一个 Topic(就是队列的概念),实际上分为了多个 Partition,发送的消息实际是分散在不同 Partition 的,所以消费顺序肯定是乱的。
解决方法1:只设置一个 Partition 了,Topic 内的消息全局有序,这就变成了 RabbitMQ 那种结构。但这种结构不符合 Kafka 的设计理念,Topic 只有一个 Partition 就失去了扩展。
解决方法2:把某一类的消息都放入同一个 Partition,保证这组消息的局部有序。在发消息的时指定 Partition Key(如用户ID,订单号),Kafka 对其进行 Hash 计算,根据计算结果决定放入哪个 Partition。
Consumer消费者有序
RabbitMQ简单队列模型,Producer 有序,MQ 内消息有序,那么 一个Consumer 接收自然是有序的。
但是如果有多个Consumer,就有可能乱序
解决方法1:RabbitMQ只能使用一个 Consumer,必定全局有序。
解决方法2:仿照 Kafka 的 Partition Key ,拆为多个队列,把同组数据放入同一个队列,实现局部有序。
Kafka 中一个 Partition 只能对应一个 Consumer,故有序。
注意
要保证消费者有序,消费者不要使用多线程