风在路上 风在路上
首页
导航站
  • Java-Se

    • Java基础
  • Java-Se进阶-多线程

    • 多线程
  • Java-Se进阶-java8新特性

    • java8新特性
  • Java-ee

    • JavaWeb
  • Java虚拟机

    • JVM
  • golang基础

    • golang基础
  • golang框架

    • gin
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • Redis
    • ElasticSearch
    • MongoDB
  • ORM

    • MyBatis
    • MyBatis-Plus
  • Spring

    • Spring
  • SpringMVC

    • SpringMVC1
    • SpringMVC2
  • SpringCloud

    • SpringCloud
  • 中间件

    • RabbitMQ
    • Dubbo
  • 秒杀项目
  • Git
  • Linux
  • Docker
  • JWT
  • 面试
  • 刷题
开发问题😈
设计模式
关于💕
归档🕛
GitHub (opens new window)

风

摸鱼
首页
导航站
  • Java-Se

    • Java基础
  • Java-Se进阶-多线程

    • 多线程
  • Java-Se进阶-java8新特性

    • java8新特性
  • Java-ee

    • JavaWeb
  • Java虚拟机

    • JVM
  • golang基础

    • golang基础
  • golang框架

    • gin
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • Redis
    • ElasticSearch
    • MongoDB
  • ORM

    • MyBatis
    • MyBatis-Plus
  • Spring

    • Spring
  • SpringMVC

    • SpringMVC1
    • SpringMVC2
  • SpringCloud

    • SpringCloud
  • 中间件

    • RabbitMQ
    • Dubbo
  • 秒杀项目
  • Git
  • Linux
  • Docker
  • JWT
  • 面试
  • 刷题
开发问题😈
设计模式
关于💕
归档🕛
GitHub (opens new window)
  • mybatis

  • mybatis-plus

  • Spring

  • SpringMvc

  • RabbitMQ

    • RabbitMQ - 知识体系
    • 中间件介绍
    • 消息队列介绍
    • RabbitMQ - 安装
    • RabbitMQ - 简单案例
    • RabbitMQ - 发布确认
    • RabbitMQ - 交换机
    • RabbitMQ - 死信队列
    • RabbitMQ - 延迟队列
    • RabbitMQ - 发布确认高级-不可路由消息处理
    • RabbitMQ - 幂等性、优先级、惰性
    • 消息队列基础
    • 消息丢失
    • 重复消费
    • 顺序消费
      • 三个阶段
      • 解决方案
        • RabbitMQ
        • RocketMQ
  • Dubbo

  • SpringCloud

  • 框架
  • RabbitMQ
zdk
2022-09-16
目录

顺序消费

Table of Contents generated with DocToc (opens new window)

  • 三个阶段
  • 解决方案
    • RabbitMQ
    • RocketMQ

# 三个阶段

  1. 消息被发送时保持顺序(producer端)

提示

Producer端确保消息顺序,唯一要做的事情就是将消息路由到特定的分区,在RocketMQ中,通过MessageQueueSelector实现分区的选择

MessageQueueSelector messageQueueSelector = new MessageQueueSelector(){
    @Override
    public MessageQueue select(List<MessageQueue> mqs,Message msg,Object arg){
        int select = arg.hashCode();
        select = select > 0 ? select : 0;
        return mqs.get(select % mqs.size());
    }
}
1
2
3
4
5
6
7
8
  1. 消息被存储时,保持和发送的顺序一致

提示

这个由mq内部保证一致

  1. 消息被消费时,保持和存储的顺序一致(consumer端)

# 解决方案

# RabbitMQ

提示

拆分为多个queue,每个queue对应一个consumer,消费者在消费的时候不去直接消费消息,而是将消息保存到内存队列(数组)中,根据消息的关键值(例如订单ID)进行哈希操作,将关键值相同的消息(一组需要保证顺序的消息)发送到相同的内存队列中去,然后分发给底层的Thread处理,一个线程只去一个内存队列中取消息,这样就保证了顺序性(可以支持高并发)。


实际中consumer的数量是受限的,不会仅仅因为消息消费太慢而去增加consumer实例的数量,所以通过这种方式,可以在不增加consumer实例数量的前提下,加快消息消费的速度。

image.png

# RocketMQ

生产者消费者一般需要保证顺序消息的话,可能就是一个业务场景下的,比如订单的创建、支付、发货、收货。


这些流程都有一个相同的订单号,可以利用这个订单号来实现顺序消费

一个topic下有多个队列,为了保证发送有序,RocketMQ提供了MessageQueueSelector队列选择机制,他有三种实现:


image.png

我们可使用Hash取模法,让同一个订单发送到同一个队列中,再使用同步发送,只有同个订单的创建消息发送成功,再发送支付消息。这样,我们保证了发送有序。


RocketMQ的topic内的队列机制,可以保证存储满足FIFO,剩下的只需要消费者顺序消费即可。


RocketMQ仅保证顺序发送,顺序消费由消费者业务保证!!!


这里很好理解,一个订单发送的时候放到一个队列里面去,同一个的订单号Hash一下是一样的结果,消费的时候肯定是同一个消费者消费,顺序就可以保证了

在 GitHub 上编辑此页 (opens new window)
#消息队列
最后更新: 2022/10/04, 16:10:00
重复消费
Dubbo知识体系

← 重复消费 Dubbo知识体系→

Theme by Vdoing | Copyright © 2022-2025 zdk | notes
湘ICP备2022001117号-1
川公网安备 51142102511562号
本网站由 提供CDN加速/云存储服务
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式