035. RocketMQ 有序消息

送分小仙女□ 提交于 2020-08-19 05:37:05

1. 有序消息的基本概念


为什么要用有序消息

image-20200716181147687

image-20200716181232385

有序消息是什么

  • 有序消息又叫顺序消息(FIFO消息)。
  • 是指消息的消费顺序和产生顺序相同,在有些业务逻辑下,必须保证顺序。
  • 比如订单的生成、付款、发货,这个消息必须按顺序处理才行。
  • 顺序消息氛围全局顺序和分区(queue)顺序。

全局消息

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

image-20200716192239379

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

分区顺序

  • 对于指定的一个 Topic,所有消息根据 sharding key 进行区块(queue)。
  • 同一个 queue 内的消息按照严格的 FIFO 顺序进行发布和消费。
  • Sharding key 是顺序消息中用来区分不同分区的关键字段,和普通消息的 key 是完全不同的概念。

image-20200716192302975

  • 适用场景:性能要求高,根据消息中的 sharding key 去决定消息发送到哪一个 queue。

全局顺序和分区顺序对比

  • 消息类型对比

    消息类型 支持事务消息 支持定时消息 性能
    无序消息(普通、事务、定时/延迟消息) 最高
    分区顺序消息
    全局顺序消息 一般
  • 发送方式对比

    消息类型 支持可靠同步发送 支持可靠异步发送 支持 Oneway 发送
    无序消息(普通、事务、定时/延迟消息)
    分区顺序消息
    全局顺序消息

2. 如何保证消息顺序


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

    • 消息被发送时保持顺序。
    • 消息被存储时保持和发送的顺序一致。
    • 消息被消费时保持和存储的顺序一致。

image-20200716192426822

3. RocketMQ 的有序消息原理


image-20200716192612142

RocketMQ 消费端类型

  • 有两种类型:MQPullConsumer 和 MQPushConsumer。

  • 本质上底层都是通过 pull 机制去实现,pushConsumer 是一种 API 封装。

  • MQPullConsumer

    • MQPullConsumer 由用户控制线程,主动从服务端获取消息,每次获取到的是一个 MessageQueue 中的消息。
    • PullResult 中的 List<MessageExt> msgFoundList 自然和存储顺序一致,用户需要在拿到这批消息后自己保证消费的顺序。
  • MQPushConsumer

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

消费消息有序性

image-20200716192701414

  • 从 Broker 中获取消息。
  • 将消息放入本地队列中。
  • 消费消息。

image-20200716192752387

  • 通过对队列加锁的方式实现有序。不同队列使用的是不同的锁。

有序消息的缺陷

发送顺序消息无法利用集群的 Failover 特性,因为不能更换 MessageQueue 进行重试因为发送的路由策略导致的热点问题,可能某一些 MessageQueue 的数据量特别大。

  • 消费的并行读依赖于 queue 数量。
  • 消费失败时无法跳过。

4. RocketMQ 有序消息的使用


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!