RocketMQ 如何保证消息的有序性?

RocketMQ 如何保证消息的有序性?

1 有序消息的基本概念

有序消息又叫顺序消息(FIFO 消息) 是指消息的消费顺序和产生顺序相同,在有些业务逻辑下,必须保证顺序。

比如设备的上线、事件上报、下线,这个消息必须按顺序处理才行。 这边顺序消息分为全局顺序和分区(queue)顺序。

1.1 全局顺序

概念

一个Topic内所有的消息都发布到同一个queue,按照先进先出的顺序进行发布和消费

全局有序性
全局有序性

适用场景

性能要求不高,所有的消息严格按照FIFO原则进行消息发布和消费的场景

2.2 分区顺序

概念

分区顺序
分区顺序

对于指定的一个Topic,所有消息根据sharding key进行(queue)分区推送

同一个queue内的消息按照严格的FIFO顺序进行发布和消费

Sharding key是顺序消息中用来区分不同分区的关键字段,和普通消息的 Key是完全不同的概念

适用场景

性能要求高,根据消息中的sharding key去决定消息发送到哪个queue

2.3 全局顺序与分区顺序对比

发送方式对比
发送方式对比

2 如何保证消息顺序

在MQ的模型中,顺序需要由3个阶段去保障

  1. 消息被发送时保持顺序
  2. 消息被存储时保持和发送的顺序一致
  3. 消息被消费时保持和存储的顺序一致
mq模型的消息顺序
mq模型的消息顺序

3 RocketMQ 的有序消息实现原理

RocketMQ消费端有两种类型:

  • MQPullConsumer
  • MQPushConsumer

底层都是通过pull机制去实现,pushConsumer是一种API封装

MQPullConsumer 由用户控制线程,主动从服务端获取消息,每次获取到的是一个MessageQueue中的消息。

PullResult中的 List<MessageExt> msgFoundList自然和存储顺序一致,用户需要再拿到这批消息后自己保证消费的顺序。

MQPushConsumer由用户注册MessageListener来消费消息,在客户端中需要保证调用MessageListener时消息的顺序性

看源码

启动消费者必须在注册完消息监听器后启动,否则会报错

  • 拉取生产端消息
  • 判断是并发的还是有序的,对应不同服务实现类

4 有序消息的缺陷

发送顺序消息无法利用集群的Failover特性,因为不能更换MessageQueue进行重试。

+3

发表评论

邮箱地址不会被公开。