RocketMQ怎么保证消息有序性?

RocketMQ在默认的情况下消息发送会采取Round Robin轮询方式把消息发送到不同的queue(分区队列);

RocketMQ在消费消息的时候从多个queue上拉取消息,这种情况发送和消费是不能保证顺序

但是如果控制发送的顺序消息只依次发送到同一个queue中,消费的时候只从这个queue上依次拉取,则就保证了顺序。

图片[1]-RocketMQ怎么保证消息有序性?-编程社

RocketMQ能严格保证消息的有序性,将顺序消息分为全局顺序消息与分区顺序消息。

  • 全局顺序:对于指定的一个 Topic,所有消息按照严格的先入先出(FIFO)的顺序进行发布和消费。
  • 分区顺序:对于指定的一个 Topic,所有消息根据hashKey进行区块分区。同一个分区内的消息按照严格的 FIFO 顺序进行发布和消费。

RocketMQ实现消息的有序性,需要从三个方面一起保证消息的有序性:

  • 生产者生产顺序消息

多线程发送的消息无法保证有序性,因此,需要业务方在发送时,针对同一个业务编号(如同一笔订单)的消息需要保证在一个线程内顺序发送,在上一个消息发送成功后,在进行下一个消息的发送。

对应到mq中,消息发送方法就得使用同步发送,异步发送无法保证顺序性

  • Broker保存顺序消息

mq的topic下会存在多个queue,要保证消息的顺序存储,同一个业务编号的消息需要被发送到一个queue中。

对应到mq中,需要使用MessageQueueSelector来选择要发送的queue,即对业务编号进行hash,然后根据队列数量对hash值取余,将消息发送到一个queue中

  • 消费者顺序消费消息:RocketMQ消费端默认消费逻辑:

1、负载均衡,指定消费者负责某些队列;

2、当前消费者开启多个线程开始同时消费这个队列,远程拉取消息。从上面消费逻辑可以看到,如果要保证消息有序消费,就要解决这两个问题,需要用到锁来保证一个队列同时只有一个消费者线程进行消费,在broker端,rocketmq是通过锁定MessageQueue的方式,来保证同一时刻,只能有一个消费者进行消费,而在消费端,rocketmq是通过synchronized锁定ConsumeRequest中的run方法,来保证一个消费者同时只能有一个线程进行消费

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称

    暂无评论内容