RocketMQ-核心篇(2)-核心概念

一、消息模型(Message Model)

  1. RocketMQ主要由 Producer、Broker、Consumer 三部分组成
    • Producer 负责生产消息
    • Consumer 负责消费消息
    • Broker 负责存储消息
  2. Broker 在实际部署过程中对应一台服务器,每个 Broker 可以存储多个Topic的消息,每个Topic的消息也可以分片存储于不同的 Broker
  3. Message Queue 用于存储消息的物理地址,每个Topic中的消息地址存储于多个 Message Queue 中
  4. ConsumerGroup 由多个Consumer 实例构成

二、消息生产者(Producer)

  1. 负责生产消息,一般由业务系统负责生产消息
  2. 一个消息生产者会把业务应用系统里产生的消息发送到broker服务器
  3. RocketMQ提供多种发送方式:同步发送、异步发送、顺序发送、延迟发送、单向发送
  4. 同步和异步方式均需要Broker返回确认信息,单向发送不需要

三、消息消费者(Consumer)

  1. 负责消费消息,一般是后台系统负责异步消费
  2. 一个消息消费者会从Broker服务器拉取消息、并将其提供给应用程序
  3. 从用户应用的角度而言提供了两种消费形式:拉取式消费、推送式消费
  4. RocketMQ中的消息消费者都是以消费者组(Consumer Group)的形式出现
    • 消费者组只是对消费者的划分,方便消息的管理
    • 例如topic是学校,tag是学生,group就是班级
      • 班级把tag分为不同组,但实际上tag都一样
  5. 消费者组是同一类消费者的集合,这类Consumer消费的是同一个Topic类型的消息
  6. 消费者组使得在消息消费方面,实现负载均衡(将一个Topic中的不同的Queue平均分配给同一个Consumer Group的不同的Consumer,注意,并不是将消息负载均衡)和容错(一个Consmer挂了,该Consumer Group中的其它Consumer可以接着消费原Consumer消费的Queue)的目标变得非常容易

image.png

  1. 消费者组中Consumer的数量应该小于等于订阅Topic的Queue数量。如果超出Queue数量,则多出的Consumer将不能消费消息

image.png

  1. 一个Topic类型的消息可以被多个消费者组同时消费
    • 消费者组只能消费一个Topic的消息,不能同时消费多个Topic消息
    • 一个消费者组中的消费者必须订阅完全相同的Topic

四、主题(Topic)

  1. 表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位
    • topic:message:1:n
    • message:topic:1:1
  2. 一个生产者可以同时发送多种Topic的消息;而一个消费者只对某种特定的Topic感兴趣,即只可以订阅和消费一种Topic的消息
    • producer:topic:1:n
    • consumer:topic:1:1

image.png

  1. 手动创建Topic时,有两种模式
    • 集群模式:该模式下创建的Topic在该集群中,所有Broker中的Queue数量是相同的
    • Broker模式:该模式下创建的Topic在该集群中,每个Broker中的Queue数量可以不同
  2. 自动创建Topic时,默认采用的是Broker模式,会为每个Broker默认创建4个Queue
  3. 读/写队列
    • 从物理上来讲,读/写队列是同一个队列,所以,不存在读/写队列数据同步问题
    • 读/写队列是逻辑上进行区分的概念,一般情况下,读/写队列数量是相同的

五、代理服务器(Broker Server)

  1. 消息中转角色,负责存储、转发消息
  2. 代理服务器在RocketMQ系统中负责接收从生产者发送来的消息并存储、同时为消费者的拉取请求做准备
  3. 代理服务器也存储消息相关的元数据,包括消费者组、消费进度偏移和主题和队列消息等

六、名字服务(Name Server)

  1. NameServer是一个Broker与Topic路由的注册中心,支持Broker的动态注册与发现
  2. 生产者或消费者能够通过名字服务查找各主题相应的Broker IP列表
  3. 多个Namesrv实例可组成集群,但相互独立,没有信息交换
  4. NameServer主要包括两个功能
    • Broker管理
      • 接受Broker集群的注册信息并且保存下来作为路由信息的基本数据
      • 提供心跳检测机制,检查Broker是否还存活
    • 路由信息管理
      • 每个NameServer中都保存着Broker集群的整个路由信息和用于客户端查询的队列信息
      • Producer和Conumser通过NameServer可以获取整个Broker集群的路由信息,从而进行消息的投递和消费
  5. 路由注册
    • NameServer通常以集群的方式部署,不过NameServer无状态,即NameServer集群中的各个节点间无差异,各节点间相互不进行信息通讯
    • 那各节点中的数据如何进行数据同步?
      • 在Broker节点启动时,轮询NameServer列表,与每个NameServer节点建立长连接,发起注册请求
      • 在NameServer内部维护着⼀个Broker列表,用来动态存储Broker的信息
    • Broker节点为了证明自己活着,会维护与NameServer间的长连接,会将最新的信息以心跳包的方式上报给NameServer,每30秒发送一次心跳
      • 心跳包中包含 BrokerId、Broker地址(IP+Port)、 Broker名称、Broker所属集群名称等等
      • NameServer在接收到心跳包后,会更新心跳时间戳,记录这个Broker的最新存活时间
  6. 路由剔除
    • 由于Broker关机、宕机或网络抖动等原因,NameServer没有收到Broker的心跳,NameServer可能会将其从Broker列表中剔除
    • NameServer中有⼀个定时任务,每隔10秒就会扫描⼀次Broker表,查看每一个Broker的最新心跳时间戳距离当前时间是否超过120秒,如果超过,则会判定Broker失效,然后将其从Broker列表中剔除
  7. 路由发现
    • RocketMQ的路由发现采用的是Pull模型。当Topic路由信息出现变化时,NameServer不会主动推送给客户端,而是客户端定时拉取主题最新的路由。默认客户端每30秒会拉取一次最新的路由
    • Push模型:推送模型实时性较好,是一个“发布-订阅”模型,需要维护一个长连接。而长连接的维护是需要资源成本的,该模型适合于的场景
      • 实时性要求较高
      • Client数量不多,Server数据变化较频繁
    • Pull模型:拉取模型存在的问题:实时性较差,但可控性较高
    • Long Polling模型:长轮询模型。其是对Push与Pull模型的整合,充分利用了这两种模型的优势,屏蔽了它们的劣势
  8. 客户端NameServer选择策略
    • 客户端在配置时必须要写上NameServer集群的地址,那么客户端到底连接哪个NameServer节点呢?
    • 客户端首先会生产一个随机数,然后再与NameServer节点数量取模,此时得到的就是所要连接的节点索引,然后就会进行连接。如果连接失败,则会采用round-robin策略,逐个尝试着去连接其它节点
    • 首先采用的是随机策略进行的选择,失败后采用的是轮询策略

七、拉取式消费(Pull Consumer)

  1. Consumer消费的一种类型,应用通常主动调用Consumer的拉消息方法从Broker服务器拉消息、主动权由应用控制
  2. 一旦获取了批量消息,应用就会启动消费过程

八、推动式消费(Push Consumer)

  1. Consumer消费的一种类型,该模式下Broker收到数据后会主动推送给消费端,该消费模式一般实时性较高

九、生产者组(Producer Group)

  1. 同一类Producer的集合,这类Producer发送同一类消息且发送逻辑一致
  2. 如果发送的是事务消息且原始生产者在发送之后崩溃,则Broker服务器会联系同一生产者组的其他生产者实例以提交或回溯消费

十、消费者组(Consumer Group)

  1. 同一类Consumer的集合,这类Consumer通常消费同一类消息且消费逻辑一致
  2. 消费者组使得在消息消费方面,实现负载均衡和容错的目标变得非常容易
  3. 要注意的是,消费者组的消费者实例必须订阅完全相同的Topic
  4. RocketMQ 支持两种消息模式:集群消费(Clustering)和广播消费(Broadcasting)

十一、集群消费(Clustering)

  1. 集群消费模式下,相同Consumer Group的每个Consumer实例平均分摊消息

十二、广播消费(Broadcasting)

  1. 广播消费模式下,相同Consumer Group的每个Consumer实例都接收全量的消息

十三、普通顺序消息(Normal Ordered Message)

  1. 普通顺序消费模式下,消费者通过同一个消息队列( Topic 分区,称作 Message Queue) 收到的消息是有顺序的,不同消息队列收到的消息则可能是无顺序的

十四、严格顺序消息(Strictly Ordered Message)

  1. 严格顺序消息模式下,消费者收到的所有消息均是有顺序的

十五、消息(Message)

  1. 消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题
  2. RocketMQ中每个消息拥有唯一的Message ID,且可以携带具有业务标识的Key
  3. 系统提供了通过Message ID和Key查询消息的功能

十六、标签(Tag)

  1. 为消息设置的标志,用于同一主题下区分不同类型的消息
    • 也就是说,一条消息是通过 topic+tag 区分
  2. 来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签
  3. 标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统
  4. 消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性
  5. Topic是消息的一级分类,Tag是消息的二级分类
    • Topic:中国省份
      • Tag:广东
      • Tag:贵州

十七、 队列(Queue)

  1. 存储消息的物理实体,一个Topic中可以包含多个Queue,每个Queue中存放的就是该Topic的消息
  2. 一个Topic的Queue也被称为一个Topic中消息的分区(Partition)
  3. 一个Topic的Queue中的消息只能被一个消费者组中的一个消费者消费
  4. 一个Queue中的消息不允许同一个消费者组中的多个消费者同时消费

注:广播模式下消息可以被多个消费者同时消费

image.png

十八、分片(Sharding)

  1. 分片不同于分区,在RocketMQ中,分片指的是存放相应Topic的Broker
  2. 每个分片中会创建出相应数量的分区,即Queue,每个Queue的大小都是相同的

image.png

十八、消息标识(MessageId/Key)

  1. RocketMQ中每个消息拥有唯一的MessageId,且可以携带具有业务标识的Key,以方便对消息的查询
  2. 不过需要注意的是,MessageId有两个:在生产者send()消息时会自动生成一个MessageId(msgId),当消息到达Broker后,Broker也会自动生成一个MessageId(offsetMsgId)
  3. msgId、offsetMsgId与key都称为消息标识
    • msgId:由producer端生成,其生成规则为:producerIp + 进程pid + MessageClientIDSetter类的ClassLoader的hashCode +当前时间 + AutomicInteger自增计数器
    • offsetMsgId:由broker端生成,其生成规则为:brokerIp + 物理分区的offset(Queue中的偏移量)
    • key:由用户指定的业务相关的唯一标识,推荐发送消息时指定,方便根据key查询消费状态

猜你喜欢

转载自blog.csdn.net/sinat_34104446/article/details/124784850