RockMq介绍

rockMq实现原理:

RocketMQ由NameServer注册中心集群、Producer生产者集群、Consumer消费者集群和若干Broker(RocketMQ进程)组成。

1、Broker在启动的时候去向所有的NameServer注册,并保持长连接,每30s发送一次心跳。

2、Producer在发送消息的时候从NameServer获取Broker服务器地址,根据负载均衡算法选择一台服务器来发送消息。

3、Conusmer消费消息的时候同样从NameServer获取Broker地址,然后主动拉取消息来消费。

 

4.RocketMQ主要的存储文件包括commitlog文件、consumequeue文件、indexfile文件

Broker在收到消息之后,会把消息保存到commitlog的文件当中,而同时在分布式的存储当中,每个broker都会保存一部分topic的数据,同时,每个topic对应的messagequeue下都会生成consumequeue文件用于保存commitlog的物理位置偏移量offset,indexfile中会保存key和offset的对应关系。

 

由于同一个topic的消息并不是连续的存储在commitlog中,消费者如果直接从commitlog获取消息效率非常低,所以通过consumequeue保存commitlog中消息的偏移量的物理地址,这样消费者在消费的时候先从consumequeue中根据偏移量定位到具体的commitlog物理文件,然后根据一定的规则(offset和文件大小取模)在commitlog中快速定位。

5.Master和Slave之间同步数据

消息在master和slave之间的同步是根据raft协议来进行的:

  1. 在broker收到消息后,会被标记为uncommitted状态
  2. 然后会把消息发送给所有的slave
  3. slave在收到消息之后返回ack响应给master
  4. master在收到超过半数的ack之后,把消息标记为committed
  5. 发送committed消息给所有slave,slave也修改状态为committed

6、RocketMQ为什么速度快?

是因为使用了顺序存储、Page Cache和异步刷盘。

  1. 我们在写入commitlog的时候是顺序写入的,这样比随机写入的性能就会提高很多
  2. 写入commitlog的时候并不是直接写入磁盘,而是先写入操作系统的PageCache
  3. 最后由操作系统异步将缓存中的数据刷到磁盘

CommitLog 文件是存放消息数据的地方,所有的消息都将存入到 CommitLog 文件中。生产者将消息发送到 RocketMQ 的 Broker 后,Broker 服务器会将「消息顺序写入到 CommitLog 文件中」,这也就是 RocketMQ 高性能的原因,因为我们知道磁盘顺序写特别快,RocketMQ 充分利用了这一点,极大的提高消息写入效率。

Consumequeue 文件可以看作是索引文件,类似于 MySQL 中的二级索引」。在存放了同一主题下的所有消息,消费者消费的时候只需要去对应的 Consumequeue 组中取消息即可。Consumequeue 文件不会存储消息的全量信息,了解 MySQL 索引的话,应该好理解这里,具体存储的字段,我在上图已经标注。这样做可以带来以下两个好处:

  • 由于 Consumequeue 文件内容小,可以尽可能的保证 Consumequeue 文件全部读入到内存,提高消费效率。
  • Consumequeue 文件也是会持久化的,不存全量信息可以节约磁盘空间。

「IndexFile」 是 RocketMQ 为消息订阅构建的索引文件,用来提高根据主题与消息队列检索消息的速度

消息数据刷盘(默认异步刷盘)

「异步刷盘方式」:消息写入到内存的 PAGECACHE中,就立刻给客户端返回写操作成功,当 PAGECACHE 中的消息积累到一定的量时,触发一次写操作,将 PAGECACHE 中的消息写入到磁盘中。这种方式「吞吐量大,性能高,但是 PAGECACHE 中的数据可能丢失,不能保证数据绝对的安全」。

「同步刷盘方式」:消息写入内存的 PAGECACHE 后,立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态。这种方式「可以保证数据绝对安全,但是吞吐量不大」。

7、什么是事务、半事务消息?怎么实现的?

事务消息就是MQ提供的类似XA的分布式事务能力,通过事务消息可以达到分布式事务的最终一致性。

半事务消息就是MQ收到了生产者的消息,但是没有收到二次确认,不能投递的消息。

实现原理如下:

  1. 生产者先发送一条半事务消息到MQ
  2. MQ收到消息后返回ack(Acknowledgement)确认
  3. 生产者开始执行本地事务
  4. 如果事务执行成功发送commit到MQ,失败发送rollback
  5. 如果MQ长时间未收到生产者的二次确认commit或者rollback,MQ对生产者发起消息回查
  6. 生产者查询事务执行最终状态
  7. 根据查询事务状态再次提交二次确认

最终,如果MQ收到二次确认commit,就可以把消息投递给消费者,反之如果是rollback,消息会保存下来并且在3天后被删除。

 

原文链接

 

CAP理论:

  • 一致性(Consistency)
  • 可用性(Availability)
  • 分区容错性(Partition tolerance)

延时消息

rocketmq 先将不同延时等级的消息存入内部对应延时队列中,然后不断的从延时队列中拉取消息判断是否到期,然后进行投递到对应的topic中。

通过固定延时等级的方式,同一个队列中的消息都是相同的延时等级,不需要对消息进行排序,只需要按顺序拉取消息判断是否可以投递就行了。但也限制了延时时间。

另外,因为只要延时消息存入延时队列中,就会写入commitlog文件中,然后rocketmq的高可用(同步复制或异步复制)就会将消息复制到slave中,从而保证延时消息的可靠性。

 

消息重试

生产端重试:如果由于网络抖动等原因,Producer程序向Broker发送消息时没有成功,即发送端没有收到Broker的ACK,导致最终Consumer无法消费消息,此时RocketMQ会自动进行重试。在5s内没有发送成功,则重试3次。

消费端重试:

异常重试:由于Consumer端逻辑出现了异常,导致返回了RECONSUME_LATER状态,那么Broker就会在一段时间后尝试重试。

超时重试:如果Consumer端处理时间过长,或者由于某些原因线程挂起,导致迟迟没有返回消费状态,Broker就会认为Consumer消费超时,此时会发起超时重试。

注:只有在消息模式为MessageModel.CLUSTERING集群模式时,Broker才会自动进行重试,广播消息是不会重试的。

死信

首先判断消息当前重试次数是否大于等于 16,或者消息延迟级别是否小于 0

只要满足上述的任意一个条件,设置新的 topic(死信 topic)为:%DLQ%+consumerGroup

进行前置属性的添加

将死信消息投递到上述步骤 2 建立的死信 topic 对应的死信队列中并落盘,使消息持久化。

消费者和生产者的重试还是有区别的,主要有两点

1、默认重试次数:Product默认是2次,而Consumer默认是16次。

2、重试时间间隔:Product是立刻重试,而Consumer是有一定时间间隔的。它照1S,5S,10S,30S,1M,2M····2H进行重试。Product在异步情况重试失效,而对于Consumer在广播情况下重试失效。

重试队列

RocketMQ 规定,以下三种情况统一按照消费失败处理并会发起重试。

  1. 业务消费方返回 ConsumeConcurrentlyStatus.RECONSUME_LATER
  2. 业务消费方返回null
  3. 业务消费方主动/被动抛出异常

rocketmq会放到重试队列。这个重试TOPIC的名字是%RETRY%+consumergroup的名字.

RocketMQ不解决消息重复问题,RocketMQ不解决消息重复问题,RocketMQ不解决消息重复问题,重要的事情说三遍。

消息持久化

RocketMQ 在持久化的设计上,采取的是「消息顺序写、随机读的策略」,利用磁盘顺序写的速度,让磁盘的写速度不会成为系统的瓶颈。并且采用 MMPP 这种“零拷贝”技术,提高消息存盘和网络发送的速度。极力满足 RocketMQ 的高性能、高可靠要求。

在 RocketMQ 持久化机制中,涉及到了三个角色:

  • 「CommitLog」:消息真正的存储文件,所有消息都存储在 CommitLog 文件中。
  • 「ConsumeQueue」:消息消费逻辑队列,类似数据库的索引文件。
  • 「IndexFile」:消息索引文件,主要存储消息 Key 与 offset 对应关系,提升消息检索速度。

消费消息的顺序性

rocketMq支持局部顺序消费,但不支持全局,换句话说针对Topic中的每个queue是可以按照FIFO进行消费。

要保证一个订单有关的消息顺序消费,有两点需要注意,一是将订单有关的消息发送到相关Topic中同一个queue里,二是消费者按照先进先出的原则进行消费。

消息发送到指定queue中

    在消息发送时,需指定对应的MessageQueueSelector,此时我们只需通过订单号与queue进行关联,代码如下。send中的参数arg即为select中的arg,将订单号作为参数传入,同一订单号的相关消息则可以保证在同一queue中。

 

 

顺序消费

如果使用MessageListenerConcurrently的话,必须保证是单线程才能顺序消费,但生产环境下,我们一般 都是多线程的形成,这样则需要使用MessageListenerOrderly。

produce在发送消息的时候,把消息发到同一个队列(queue)中,消费者注册消息监听器为MessageListenerOrderly,这样就可以保证消费端只有一个线程去消费消息

注意:是把把消息发到同一个队列(queue),不是同一个topic,默认情况下一个topic包括4个queue

 MessageListenerConcurrently使用代码如下

 

 MessageListenerOrderly使用代码如下

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: RockMQ支持三种消费模式: 1. 同步消费模式(Synchronous),消费者接收到消息后进行处理,处理完成后才会返回消息认为消费成功,否则返回消费失败。 2. 异步消费模式(Asynchronous),消息马上返回给消费者,处理时间不确定,消费者处理完成后,通过回调函数通知RockMQ处理结果。 3. 单向消费模式(One-way),发送消息到消息队列后,不需要等待消费者处理成功的确认反馈,属于一种较为简单高效的方式。 ### 回答2: RockMQ 消费模式有以下几种: 1. 集群模式:多个消费者以集群的形式消费消息。在集群模式下,通过消息负载均衡算法,消息将被平均分布给不同的消费者进行处理。 2. 广播模式:所有注册的消费者都会接收到相同的消息副本。广播模式适用于需要所有消费者都处理同一份消息的场景,如日志记录等。 3. 广播异步模式:广播模式下,消息的消费由消费者自行管理。通过异步方式进行消息的接收和处理,提高处理效率。 4. 顺序消息模式:保证消息按照特定的顺序进行消费。通过发送消息时给定的订单号或者其他有序标识,确保消费者按照相同的顺序进行处理。 以上就是 RockMQ 的几种消费模式,根据实际需求选择适合的模式能够提高消息处理的效率和可靠性。 ### 回答3: RockMQ消费模式主要有以下几种: 1. 集群模式:在集群模式下,多个消费者可以同时消费同一个队列的消息。RockMQ采用了负载均衡机制来确保消息在多个消费者之间的均衡消费。当一个消费者挂掉时,其他消费者会自动接管该消费者的消息消费。 2. 广播模式:广播模式下,每个消费者都会收到同一条消息。这种模式适用于需要多个消费者同时处理相同消息的场景,比如日志记录。 3. 负载均衡模式:负载均衡模式是针对集群模式的一种优化。在负载均衡模式下,消息消费按照消息的哈希值进行分配,相同哈希值的消息会被分配到相同的消费者上,以保证消息的有序性。 4. 延迟消费模式:延迟消费模式允许消费者延迟消费某些特定的消息。消费者可以设置延迟时间,消息将在指定延迟时间后才被消费。这种模式适用于某些需要时间处理的消息,比如定时任务。 总体来说,RockMQ提供了多种消费模式来满足不同场景下的需求。无论是集群模式、广播模式还是负载均衡模式,RockMQ都保证了高性能和可靠性,能够满足大规模分布式系统的消息处理需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值