想实现消息有序,需要从 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,故有序。

注意

要保证消费者有序,消费者不要使用多线程