MQ整体流程分析

166 阅读6分钟

对掘金小册以及各种文档学习的笔记总结

一、基本概念

  1. RocketMQ由四个部分组成,分别是Producer、Consumer、Broker、NameServer。
    1. Producer:消息生产者,业务端负责发送消息
    2. Consumer:消息消费者,负责消费消息
    3. Broker:消息存储和中转角色,负责接收、存储和转发消息
    4. NameServer:管理所有其他组件,多NameServer时每一个都管理所有组件
  2. 消息Message就是要传输的信息,有以下相关参数。
    1. Topic:Topic(主题)可以看做消息的归类,它是消息的第一级类型。Topic 与生产者和消费者的关系非常松散,一个 Topic 可以有0个、1个、多个生产者向其发送消息,一个生产者也可以同时向不同的 Topic 发送消息。一个 Topic 也可以被 0个、1个、多个消费者订阅。
    2. Tag:Tag(标签)可以看作子主题,它是消息的第二级类型,用于为用户提供额外的灵活性。使用标签,同一业务模块不同目的的消息就可以用相同 Topic 而不同的 Tag 来标识。一条消息可以没有 Tag
    3. Group:RocketMQ中,订阅者的概念是通过消费组(Consumer Group)来体现的。每个消费组都消费主题中一份完整的消息,不同消费组之间消费进度彼此不受影响,也就是说,一条消息被ConsumerGroup1消费过,也会再给ConsumerGroup2消费。消费组中包含多个消费者,同一个组内的消费者是竞争消费的关系,每个消费者负责消费组内的一部分消息。
    4. MessageQueue:Message Queue(消息队列),一个 Topic 下可以设置多个消息队列,Topic 包括多个 Message Queue ,一个Topic的多个消息队列可以在不同Broker上,如果一个 Consumer 需要获取 Topic下所有的消息,就要遍历所有的 Message Queue。
    5. Offset:在Topic的消费过程中,由于消息需要被不同的组进行多次消费,所以消费完的消息并不会立即被删除,这就需要RocketMQ为每个消费组在每个队列上维护一个消费位置(Consumer Offset),这个位置之前的消息都被消费过,之后的消息都没有被消费过,每成功消费一条消息,消费位置就加一。

二、消费流程

消息消费整体流程为Producer->Broker->Consumer,接下来从producer开始介绍

  1. Producer相关特性:

    • 发送消息模式:
      1. 异步消息:producer向broker发送消息时指定消息发送成功及发送异常的回调方法,调用API后立即返回,producer发送消息线程不阻塞,消息发送成功或失败的回调任务在一个新的线程中执行。
      2. 同步消息:producer向broker发送消息,执行API时同步等待,直到broker服务器返回发送结果。
      3. 顺序消息:consumer按照发送消息的先后顺序获取消息,从而实现业务场景中的顺序处理。
      4. 单向消息:producer向broker发送消息,执行API时直接返回,不等待broker服务器的结果。
      5. 事务消息:发送消息并异步执行,需要创建TransactionMQProducer,实现TransactionListener接口中的两个方法:
        • executeLocalTransaction:半事务发送成功后,本地的事务逻辑
        • checkLocalTransaction:二次确认时没有收到,broker向本地请求事务状态的方法
    • 负载均衡:Producer向MessageQueue中发送消息,一个Topic中有多个MessageQueue,Producer的负载均衡就是保证消息向各MessageQueue发送消息相同,有两种实现类型:
      1. RocketMQ默认实现:
        1. 主逻辑:轮询MessageQueue,通过自增取余的方式找到MessageQueue 2. 对Broker的避让逻辑:如果消息发送失败,则下次发送时会优先避开上一次MessageQueue所在的Broker,如果没有符合条件的MessageQueue再运行主逻辑。 producer负载均衡 - 副本.jpg
      2. 通过MessageQueueSelector定义选择策略,有三种MessageQueue选择方式:
        • SelectMessageQueueByHash:按照Hash值区分()
        • SelectMessageQueueByMachineRoom:按照机房区分(需要自己实现)
        • SelectMessageQueueByRandom:随机分配
        • 重写MessageQueueSelector自定义选择方式
  2. Broker相关特性:

    1. 心跳:

      • 第一次延迟10s,间隔根据config配置确定,配置时间应该在10s~60s之间,默认30s
      • 向所有nameserver更新该Broker上的Topic信息
    2. 接收消息:

      • 可以通过storePathCommitLog配置存储地址,项目中存储在/opt/store/commitlog中,其中存储的CommitLog按照起始偏移量命名
    3. 刷盘:MQ收到的消息通过内存队列方式在DefaultMessageStore中执行存储操作,在config中通过flushDiskType进行修改。

      • 异步刷盘:默认配置消息存入内存后直接返回写成功状态,500ms执行一次刷盘,每次刷16K数据,缺点是可能造成消息丢失,优点是吞吐量大。
      • 同步刷盘:消息写入内存后,立刻通知刷盘线程刷盘,等待刷盘完成后,刷盘线程执行完成后返回消息写成功的状态。
    4. 存储消息方法调用:

      存消息流程.png

  3. Consumer相关特性:

    1. 类型:分为Push与Pull,5.0版本添加POP

      • Push:Broker Push to Consumer,理解为broker一直往consumer发消息(实际本质上也是在Consumer实现pull),实时性较好,但是如果存在慢消费,容易造成消息堆积
      • Pull:Consumer Pull from Broker,理解为consumer批量从broker拉取
      • Pop:只能与Push互相转换,一个Queue可以对应多个Consumer,也可以避免Consumer服务hang导致的消息积压,POP消费模式分析
      • 有三个实现类:DefaultMQPushConsumer、DefaultMQPullConsumer、DefaultLitePullConsumer,其中DefaultMQPullConsumer使用比较复杂,已被弃用,由Lite替换
    2. 相关参数:

      • messageModel:广播与集群消费模式,在集群消费模式下同一个ConsumerGroup的所有消费者共同消费一个Topic
      • consumeFromWhere:消费者消费起始位置,CONSUME_FROM_TIMESTAMP:从指定的时间戳开始消费,默认为消费者启动之前的30分钟处开始消费、CONSUME_FROMFIRST_OFFSET:从最小偏移量开始消费、CONSUME_FROM_MAX_OFFSET:从最大偏移量开始消费(已弃用)
      • messageListener:设置对消息的消费逻辑
      • offsetStore:存储该消费者消费进度,与messageModel有关,广播模式消费进度保存在本地,集群模式保存在远端
    3. 负载均衡: 主要通过对consumer订阅topic的messageQueue重新分配,若同一个ConsumerGroup中的Consumer订阅了不同Topic,会导致messageQueue分配出错,部分消息无法消费。在集群模式中,如果MessageQueue数量小于Consumer数量,则会导致部分Consumer分配不到MessageQueue,无法起到提高消费速度的作用。

    4. 消费消息

      consumer.png