■ RocketMQ有序消息的使用

1 为什么需要消息的有序性

比如用户张三终于挣了一百存在在银行卡里存取款,对应两个异步的短信消息,肯定要保证先存后取吧,不然都没钱怎么发了取钱的消息呢!
M1 - 存钱
M2 - 取钱

RocketMQ 实战(三) - 消息的有序性
而mq默认发消息到不同q显然是行不通的,会乱序
需要发往同一个q,先进先出

2 有序消息的基本概念

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

比如订单的生成、付款、发货,这个消息必须按顺序处理才行。
顺序消息分为全局顺序和分区(queue)顺序

2.1 全局顺序

概念

一个Topic内所有的消息都发布到同一个queue,按照先进先出的顺序进行发布和消费
RocketMQ 实战(三) - 消息的有序性

适用场景

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

2.2 分区顺序

概念

RocketMQ 实战(三) - 消息的有序性

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

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

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

适用场景

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

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

发发送方式对比
RocketMQ 实战(三) - 消息的有序性

3 如何保证消息顺序

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

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

RocketMQ 实战(三) - 消息的有序性

4 RocketMQ 的有序消息实现原理

RocketMQ 实战(三) - 消息的有序性

RocketMQ消费端有两种类型:

  • MQPullConsumer
  • MQPushConsumer

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

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

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

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

RocketMQ 实战(三) - 消息的有序性
RocketMQ 实战(三) - 消息的有序性

看源码
RocketMQ 实战(三) - 消息的有序性
RocketMQ 实战(三) - 消息的有序性
RocketMQ 实战(三) - 消息的有序性

  • 拉取生产端消息
    RocketMQ 实战(三) - 消息的有序性
  • 判断是并发的还是有序的,对应不同服务实现类
    RocketMQ 实战(三) - 消息的有序性

5 有序消息的缺陷

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

因为发送的路由策略导致的热点问题,可能某一些MessageQueue的数据 量特别大
◆ 消费的并行读依赖于queue数量
◆ 消费失败时无法跳过

6 使用

见官网Order-example

相关文章: