09 微服务组件 - RocketMQ消息中间件

320 阅读6分钟

一发一存一消费,没有最好的消息中间件,只有最合适的消息中间件。

1. RocketMQ保姆级教程

RocketMQ整体架构: image.png

  • Producer:消息生产者,它会先和NameServer集群中的随机一台建立长连接,以获取当前要发送的Topic存在哪些BrokerMaster上,然后和每个BrokerMaster建立长连接,发送消息时根据负载均衡算法(轮训、哈希、随机等)选择一个BrokerMaster进行发送
  • Consumer:消息消费者,它也会先和NameServer集群中的随机一台建立长连接,以获取当前要消费的Topic存在哪些BrokerMaster、Slave上,然后消费者会与每个Broker的Master或Slave建立长连接,以进行消息消费。支持集群消费和广播消费消息。
  • Broker:主要负责消息的存储、查询消费,支持主从部署,一个Master可以对应多个Slave,Master支持读写,Slave只支持读。Broker会向集群中的每一台NameServer注册自己的路由信息。
  • NameServer:简单的Topic路由注册中心,支持Broker的动态注册和发现,保存Topic和Borker之间的关系。通常也是集群部署,但是各NameServer之间不会互相通信,各NameServer都有完整的路由信息。

RocketMQ工作流程:

  1. 先启动NameServer集群,各NameServer之间无任何数据交互,Broker启动之后会向所有NameServer定期(每30s)发送心跳包,包括:IP、Port、TopicInfo,NameServer会定期扫描Broker存活列表,如果超过120s没有心跳则移除此Broker相关信息,代表下线。
  2. 这样每个NameServer就知道集群所有Broker的相关信息,此时Producer上线从NameServer就可以得知它要发送的某Topic消息在哪些Broker上,决策出一个BrokerMaster发送消息。
  3. Consumer上线也可以从NameServer得知它所要接收的Topic是哪些Broker,和对应的Master、Slave建立连接,接收消息。

2. RocketMQ分享

RocketMQ使用场景:

什么时候不用mq? 
    当调用某个下游系统的时候,需要【实时知道明确结果后才能进行后一步同步接口的动作】。
    比如:交易里的预占库存或扣库存操作。
    
什么时候用mq?
    a.解耦(非核心链路mq通知到就行)
        当你完成一个动作后,有某些下游需要知道你动作的结果(可能是特定的下游、可能是不特定的下游),
        而这些下游是如何消费如何处理你的结果的这个过程你是不关心的情况下,
        则可以使用发送mq的形式来解耦对上下游的关系。比如:支付完成发送支付成功的消息。
    b.异步(下游处理慢,mq通知然后回查)
        需要关心下游调用结果,但是下游处理时间RT过长,C端无法接受时,使用异步的手法来提高调用吞吐率,
        可以使用mq或者线程池等方案来处理的业务场景,当然最后需要回调通知给调用方或者提供结果查询接口的方式。
    c.削峰(下游无法承接大量瞬时流量)
        秒杀场景时,下游处理能力有限,无法承载大量瞬时流量,发送mq通知,下游根据服务消费能力去拉取消费。

RocketMQ Blocker介绍: image.png

RocketMQ存储用的是本地文件存储系统,效率高也可靠。
主要涉及到三种类型的文件,分别是 CommitLog、ConsumeQueue、IndexFile。

1. CommitLog
RocketMQ的所有主题的消息都存在CommitLog中,单个CommitLog默认1G,并且文件名以起始偏移量命名,固定20位,
不足则前面补0,比如00000000000000000000代表了第一个文件,第二个文件名就是 00000000001073741824,
表明起始偏移量为 1073741824,以这样的方式命名用偏移量就能找到对应的文件。所有消息都是顺序写入的,
超过文件大小则开启下一个文件。

2. ConsumeQueue
ConsumeQueue消息消费队列,可以认为是CommitLog中消息的索引,因为【CommitLog是糅合包含了所有主题的消息,
所以通过索引才能更加高效的查找消息。消费者是先从ConsumeQueue来得到消息真实的物理地址,
然后再去CommitLog获取消息。】

ConsumeQueue存储的条目是固定大小的,8字节的commitlog物理偏移量,4字节的消息长度和8字节Tag的哈希值,
固定20字节。在实际存储中,【ConsumeQueue对应的是一个Topic下的某个Queue】,每个文件约5.72M,有30w条数据。

3. IndexFile
IndexFile就是索引文件,是额外提供查找消息的手段,不影响主流程。通过Key或者时间区间来查询对应的消息。

3. Rocket MQ(四)Topic,Topic分片和Queue

RocketMQ Topic分片和Queue: image.png 对于RocketMQ,一个Topic可以分布在各个Broker上,我们可以把一个Topic分布在一个Broker上的子集定义为一个Topic分片。将Topic分片再切分为若干等分,其中的一份就是一个Queue。每个Topic分片等分的Queue的数量可以不同,由用户在创建Topic时指定。

Topic分片的主要目的是突破单点的资源(网络带宽,CPU,内存或文件存储)限制从而实现水平扩展(不够了再加Broker)。RocketMQ在进行Topic分片以后,已经达到水平扩展的目的了,为什么还需要进一步切分为Queue呢?

借用Rocket MQ官方文档中的Consumer负载均衡示意图来说明: Queue消费图 在一个Consumer Group内,Queue和Consumer之间的对应关系是一对多的关系:一个Queue最多只能分配给一个Consumer,一个Cosumer可以分配得到多个Queue。这样的分配规则,每个Queue只有一个消费者,可以避免消费过程中的多线程处理和资源锁定,有效提高各Consumer消费的并行度和处理效率。

4. 手把手带你了解消息中间件(3)——RocketMQ

RocketMQ架构图: image.png Broker在启动的时候会去向NameServer注册并且定时发送心跳,Producer在启动的时候会到NameServer上去拉取Topic所属的Broker具体地址,然后向具体的Broker发送消息

RocketMQ基本概念: image.png image.png image.png

5. RocketMQ的push消费方式实现的太聪明了

MQ消费方式:Pull、Push

  • Push消费:响应快、实时性高,MQ收到消息立马能推送给消费者;无法控制MQ推送速度,消息量大时对消费者压力较大;
  • Pull消息:主动去MQ拉取消息,消费者压力可控;实时性差,取决于拉取间隔。

RocketMQ消费实现:Pull+长轮询实现伪Push image.png

6. RocketMQ消息短暂而又精彩的一生

写得太赞了orz!!! image.png

7. 问问ChatGPT

在RocketMQ中,用户在创建Topic的过程是怎么样的?

image.png

在rocketMQ中,消费者对每个消费组维护一个线程池,还是所有消费组共用一个线程池去拉取数据?

image.png