RocketMq

  1. 概述rocket mq

消息中间件是基于队列与消息传递技术,在网络环境中为应用系统提供同步或异步、可靠的消息传输的支撑性软件系统  RocketMQ是阿里云基于 Apache RocketMQ 构建的低延迟、高并发、高可用、高可靠的分布式消息中间件,今天了解下它。 

  1. rocket mq中间件的架构图

  1. rocket mq基本组件概念

RocketMQ主要由 Producer、Broker、Consumer Nameserver部分组成,其中Producer 负责生产消息,Consumer 负责消费消息,Broker 负责存储消息Nameserve负责协调管理前三者,它管理两部分数据:集群的Topic-Queue的路由配置;Broker的实时配置信息。其它模块通过Nameserve提供的接口获取最新的Topic配置和路由信息。

Rocketmq的一些名词解释

主题(Topic)

表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。

代理服务器(Broker Server)

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

名字服务(Name Server)

名称服务充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的Broker IP列表。多个Namesrv实例组成集群,但相互独立,没有信息交换。

拉取式消费(Pull Consumer)

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

推动式消费(Push Consumer)

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

生产者组(Producer Group)

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

消费者组(Consumer Group)

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

集群消费(Clustering)

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

广播消费(Broadcasting)

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

普通顺序消息(Normal Ordered Message)

 普通顺序消费模式下,消费者通过同一个消费队列收到的消息是有顺序的,不同消息队列收到的消息则可能是无顺序的。

严格顺序消息(Strictly Ordered Message)

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

代理服务器(Broker Server)

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

消息(Message)

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

标签(Tag)

为消息设置的标志,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。

  1. 使用rocket mq核心流程
  1. 启动Nameserver
  2. Broker都注册到Nameserver上
  3. Producer从Nameserver上获取发消息的topic信息
  4. Producer发消息
  5. Producer向提供服务的所有master建立长连接,且定时向master发送心跳
  6. Consumer通过NameServer集群获得Topic的路由信息
  7. Consumer会与所有的Master和所有的Slave都建立连接进行监听新消息
  8. Consumer接听消息
  1. 使用rocket代码示例

引入依赖

Application.yaml添加配置

server:
  port: 8082

rocketmq:
  name-server: 127.0.0.1:9876
  producer:
    group: my-producer-group


logging:
  file:
    path: /usr/log/mqproductservice/mqproductservice.log
  level:
    root: INFO
    com.anran.projectmanage.mapper: DEBUG


spring:
  cloud:
    stream:
      bindings:
        output: { destination: test-topic,content-type: application/json }
      rocketmq:
        binder:
          name-server: 127.0.0.1:9876

定义消息生产者类,并且注入rocketmq-client-starter包里面的JMQTemplate类,该类定义好了生产者发送消息的方法

定义消息消费者类并且实现JMQListener,引入的rocketmq-client-starter包里面有获取在application.yaml配置的需要监听的消费者topc主题的配置类rocketMQProperties,通过消费者类里面的getTopic()能监听改top主题需要消费的消息,消费消息的逻辑则在消费者类 onMessage()的方法中。

  1. Rocketmq的消息生产者与消费者

生产者和消费者是消息队列的两个重要角色,生产者向消息队列写入数据,消费者从消息对立读取数据,RockketMQ的大部分用户只需要和生产者、消费者打交道,现在来了解下他们的特点已经它们相关的offet和log。

rocketMQ的消息模型

一个Topic(消息主题)可能对应多个实际的消息队列(MessgeQueue) 

在底层实现上,为了提高MQ的可用性和灵活性,一个Topic在实际存储的过程中,采用了多队列的方式,具体形式如上图所示。每个消息队列在使用中应当保证先入先出(FIFO,First In First Out)的方式进行消费。 那么,基于这种模型,就会引申出两个问题:

  • 生产者 在发送相同Topic的消息时,消息体应当被放置到哪一个消息队列(MessageQueue)中?
  • 消费者 在消费消息时,应当从哪些消息队列中拉取消息?

消息的系统间传递时,会跨越不同的网络载体,这会导致消息的传播无法保证其有序。

深入了解下MQ的消息投递机制

我们先来看看生产者(producer)的投递消息策略

  1. 默认的投递方式:基于queue队列的轮训算法投递

默认情况下,采用了最简单的轮训算法,这种算法有个很好的特性就是,保证每一个queue的消息投递数量尽肯能均匀,

  1. 默认投递方式的增强:基于queue队列轮训算法和消息投递延迟最小的策略投递

默认的投递方式比较简单,但是也暴露了一个问题,就是有些queue队列可能由于自身数量挤压等原因,可能在投递的过程比较长,对于这样的queue队列会影响后续投递的效果。

基于这种现象,rocketMQ在每发送一个MQ消息后,都会统计一下消息投递的时间延迟,根据这个时间延迟,可以知道往哪个queue队列的投递的速度快

在这种场景,会优先使用消息投递延迟最小的策略,如果没有生效再使用queue队列轮训的方式。

  1. 顺序消息的投递方式

上述的两种投递方式属于对消息投递的时序性没有要求的场景,这种投递的速度和效率比较高。但是在有些场景下,需要保证同类型消息投递和消费的顺序性。

例如,假设现在有TOPIC-TOPIC_SALE_ORDER,该topic下有4个queue队列,该topic用与传递订单的状态变迁,未支付、已支付、发货中(处理中)、发货成功、发货失败。

在时序上,生产者从时序上可以生产如下几个消息:

订单T0000001:未支付 –->订单T0000001:已支付 –->

订单T0000001:发货中(处理中) –->订单T0000001:发货失败,这种情况下我们希望消费者消费消息和我们发送的一致。

如下图

RocketMQ在生产者消息投递的过程中,使用了MessageQueueSelector作为队列选择的策略接口,其定义如下:

 

相应的,目前rocketMQ也提供了如下几种实现: 

默认实现:

投递策略

策略实现类

说明

随机分配策略

SelectMessageQueueByRandom

使用了简单的随机数选择算法

基于Hash分配策略

SelectMessageQueueByHash

根据附加参数的Hash值,按照消息

队列列表的大小取余数,得到消息队列

的index

基于机器机房位置分配策略

SelectMessageQueueByMachineRoom

开源的版本没有具体的实现,

基本的目的应该是机器的就近原则分配

既然说了消息的投递queue策略,那么也来了解下rocketMQ消费者分配queue队列

RocketMQ对于消费者消费消息有两种形式:

  • BROADCASTING:广播式消费,这种模式下,一个消息会被通知到每一个消费者
  • CLUSTERING: 集群式消费,这种模式下,一个消息最多只会被投递到一个消费者上进行消费

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值