RocketMQ总结

Posted 东瓜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RocketMQ总结相关的知识,希望对你有一定的参考价值。

多个mq如何选型

  • RocketMQ

    • Java开发
    • 集群化,效率高,每秒可处理几十万条消息
    • 有消息查询界面
    • 消息可靠性高
  • Kafka

    • Scala开发
    • 效率高
    • 消息丢失概率大,适合做日志收集、埋点上报等业务
  • RabbitMQ

    • erlang开发
    • 对消息堆积支持不友好
  • ActiveMQ

    • Java开发,简单、稳定,效率不高

MQ的作用

  • 解耦

    • 上游发mq,下游订阅,上游不需要关心有哪些下游系统,不需要与下游直接交互
  • 异步

    • 不需要同步执行的业务逻辑,异步处理,减少响应时间
  • 削峰

    • 后端Service可以保持固定速率消费,甚至停止消费,保证系统不被压垮

RocketMQ从消费发送到消费的执行流程

  1. Producer发送消息到Broker,负载均衡策略默认随机
  2. Broker接收消息,写入PageCage,返回成功
  3. Broker刷盘,消息存储Consumer queue、commit log
  4. Consumer从Broker拉取消息,拉取方式长轮询pull
  5. Consumer消费消息,处理业务逻辑
  6. Consumer返回ACK,更新Broker offset
  7. 消费失败,消息转入失败队列
  8. Broker的ScheduleService从重试队列拉取消息,重放这个消息
  9. 重试16次如果还是失败,消息进入死信队列
  10. 通过RocketMQ操作面板监控死信队列,手动处理

RocketMQ如何做负载均衡

Topic在Broker集群中分布式存储

Producer端:轮询
Consumer端:平均分配策略,一个队列最多被一个消费组的一个Consumer消费,一个Consumer可以消费多个队列

RocketMQ如何保证消息不丢失

1、Producer端

  • 采取send()同步发消息,发送结果是同步感知的。
  • 发送失败后可以重试,设置重试次数。默认3次。
producer.setRetryTimesWhenSendFailed(10);
  • 集群部署,比如发送失败了的原因可能是当前Broker宕机了,重试的时候会发送到其他Broker上。

2、Broker端

  • 修改刷盘策略为同步刷盘
  • 修改主从复制策略为同步复制

3、Consumer端

  • 消费成功后会返回ACK,更新Broker的offset

消息丢失的场景

  1. 异步刷盘,Broker宕机,未完成刷盘
  2. 异步复制,主Broker宕机,未完成复制

重复消费问题

1、造成重复消费的原因

  • Consumer消费完,宕机,未返回ACK
  • Consumer消费完,返回ACK,网络断开,Broker未收到
  • 主Broker更新ACK,副Broker未复制,主Broker宕机

2、解决
业务方控制幂等

  • 定义业务幂等字段,数据库定义为唯一键

怎么发送顺序消息

  • 将消息发送到同一个队列中
  • 通过重写MessageQueueSelector接口,将不同的消息发送到指定的队列
  • Consumer消费的时候如果是多线程,需要先使用synchronize获取锁
  • 一条消息消费失败,将阻塞整个队列,所以一般不用

RocketMQ效率高的原因

  • 分区并行。每个Topic可以设置多个MessageQueue(Partition),可以对应多个消费者实现并行处理
  • 顺序写磁盘。对commit log采用追加写的方式,新消息被追加到文件的末端
  • 利用页缓存PageCache。Broker收到数据后,写入PageCache即算成功,由操作系统自己控制刷盘
  • 零拷贝。消费者可以直接从PageCache读取数据,减少了数据复制次数,避免了用户态与内核态之间的切换
  • 使用Netty框架实现高性能的网络传输

RocketMQ与Kafka的异同

1、定位

  • Kafka定位高吞吐,对消息重复、丢失没严格要求,适用数据量超大的日志收集、埋点数据收集等常见
  • RocketMQ思路源于Kafka,提供了更可靠的消息传输,具备高吞吐、高可用特性,适用大规模分布式系统应用

2、单机支持队列数

  • Kafka队列数超过64个性能会下降,对多个Partition文件的顺序写在操作系统层面变成了随机写
  • RocketMQ队列数增多效率无明显下降,因为数据存储在一个commit log

3、数据可靠性

  • Kafka使用异步刷盘,异步主从复制,Producer只支持异步发送消息,且会积攒一批消息一起发
  • RocketMQ支持同步刷盘,同步主从复制,Producer发送消息支持同步、异步、单向三种模式

4、当时消息

  • Kafka不支持
  • RocketMQ支持level级别的定时消息

5、消息失败重试

  • Kafka不支持
  • RocketMQ支持时间level级别的重试

以下RocketMQ支持,Kafka不支持:

6、分布式事务消息
7、顺序消息
8、消息查询
9、消息回溯

RocketMQ消息底层存储模型

  • CommitLog存储真正的消息体
  • ConsumerQueue是CommitLog的索引文件,存储消息在CommitLog的物理偏移量,消息大小,tag的hashCode
  • IndexFile是面板查询的索引文件

定时消息实现原理

  1. 延迟级别大于0表示延迟消息,将消息转存到SCHEDULE_TOPIC_XXX队列
  2. ScheduleService定时任务拉取延时队列中的消息(未到延时时间则延迟100毫秒再拉)
  3. 根据偏移量从CommitLog拉取消息体
  4. 恢复成原来的消息主题,将消息投递到原主题队列

消息堆积如何处理

1、增加Consumer,增加MessageQueue,增加Consumer线程数
2、新建一个Topic,先消费将消息搬运到另外一个Topic,后用新Consumer消费处理

分布式事务消息实现原理

Half Message:预处理消息,当broker收到此类消息后,会存储到RMQ_SYS_TRANS_HALF_TOPIC的消息消费队列中

检查事务状态:Broker会开启一个定时任务,消费RMQ_SYS_TRANS_HALF_TOPIC队列中的消息,每次执行任务会向消息发送者确认事务执行状态(提交、回滚、未知),如果是未知,Broker会定时去回调在重新检查。

超时:如果超过回查次数,默认回滚消息。

也就是他并未真正进入Topic的queue,而是用了临时queue来放所谓的half message,等提交事务后才会真正的将half message转移到topic下的queue。

其他

RocketMQ消费模式有几种?

消费模型由Consumer决定,消费维度为Topic。

  • 集群消费
1.一条消息只会被同Group中的一个Consumer消费

2.多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据

  • 广播消费
消息将对一 个Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。

如果让你来动手实现一个分布式消息中间件,整体架构你会如何设计实现?

  • 支持集群,支持快速扩容
  • 消息存储模型
  • 高性能
  • 高可用性
  • 数据0丢失的考虑

以上是关于RocketMQ总结的主要内容,如果未能解决你的问题,请参考以下文章

RocketMq在SparkStreaming中的应用总结

RocketMQ知识图谱总结

RocketMQ总结

rocketMQ简单总结

rocketMQ简单总结

RocketMQ吐血总结