RocketMQ学习笔记

1 前言

  1. RocketMQ特性
  2. 基本概念

1.1 RocketMQ特性

  • 原生分布式
    • 设计的时候就考虑到分布式,相较于ActiveMQ存在的单点故障问题,RocketMQ天生就支持分布式集群
  • 两种消息拉取方式
  • 严格消息顺序
  • 特有的分布式协调器
  • 亿级消息堆积
  • 组(Group)
    • 分组可以实现消息的负载均衡

1.2 RocketMQ基本概念

  • Producer:消息生产者,负责生产消息,一般由业务系统负责生产消息,如订单系统
  • Consumer:消息消费者,负责消费消息,一般是后台系统负责异步消费,如短信系统
  • Push:broker接收到消息后,推送消息给Consumer,由于Consumer消费消息的速率不同,因此有可能造成消息堆积和网络拥堵
  • Pull:Consumer主动向broker拉取消息,适用于不同速率的Consumer消费消息的情景
  • Broker:消息中转者(RocketMQ Server),负责存储消息,转发消息
  • Topic:消息的主题,通常一个业务系统一个Topic,用于消息分类,也就是Consumer可以按照主题进行订阅,在RockerMQ Server进行配置
  • Message:在Producer、Consumer和Broker之间传递的消息,一个Message必须属于一个Topic
  • Offset:偏移量,Consumer拉取消息时需要知道上一次消费到了什么位置,这一次从哪里开始拉取
  • Partition:分区,Topic物理上的分区,一个Topic可以分为多个分区,每一个分区是一个有序的队列,分区中的每条消息都会给分配一个有序的ID,也就是偏移量
  • Tag:用于对Message进行过滤,同一业务不同目的的Message可以使用相同的Topic,但是可以用不同的Tag来区分
  • Key:消息的Key字段是为了唯一表示消息的,为了方便开发和运维定位问题,如Key可以是订单ID
  • NameServer:注册中心,可以集群部署,每一个Broker启动时,都会向NameServer注册,主要是接收客户端的路由请求并返回路由信息
  • Consumer Group:每个Consumer对应一个特定Group,可以为单个Consumer指定Group,不指定则在默认Group,同一Topic的一条消息只能被同一Group的一个Consumer消费,保证了不会被重复消费,但该消息可以被多个Group消费

2 架构方案

为了避免出现单点故障,在实际生产环境中,会把Producer、Consumer、Broker和NameServer部署成集群,Producer、Consumer会跟NameServer建立长连接,用于发现Broker;Broker自动伸缩、故障或者升级都会更新NameServer中的注册信息

  • Producer Cluster:查询NameServer集群,根据返回的路由信息(负载均衡),往Broker集群发送消息
  • NameServer Cluster:存储当前集群所有的Broker信息、Topic跟Broker的对应关系
  • Broker Cluster:向NameServer集群注册,Broker Master和Broker Slave会进行数据同步
  • Consumer Cluster:查询NameServer集群,根据返回的路由信息(负载均衡),从Broker集群拉取消息

3 有序消息

  1. 全局顺序
  2. 分区顺序
  3. 全局顺序与分区顺序对比
  4. RocketMQ顺序消息的实现

3.1 全局顺序

一个Topic内所有的Message都发布到同一个queue,按照先进先出的顺序进行发布和消费

  • 适用场景:性能要求不高,所有的消息严格按照FIFO原则进行消息发布和消费

3.2 分区顺序

对于指定的一个Topic,所有消息根据sharding key发布到不同queue,同一queue中的消息严格按照FIFO原则进行消息发布和消费

  • 适用场景:性能要求高,根据消息中的sharding key决定消息发送到哪个queue

3.3 全局顺序与分区顺序对比

消息类型支持事务消息支持定时消息性能
无序消息(普通、事务、定时、延迟消息)最高
全局顺序消息一般
分区顺序消息

3.4 RocketMQ顺序消息的实现

大魔王

4 订阅机制和定时消息

  • RocketMQ发布订阅
  • Push(推模式)
  • Pull(拉模式)
  • 延迟级别
  • Broker定时消息发送逻辑

4.1 RocketMQ发布订阅

  • Push模式(MQPushConsumer):Broker主动向消费者推送
  • Pull模式(MQPullConsumer):消费者在需要消息时,主动到Broker拉取

但是,在RocketMQ中,具体实现时,Push和Pull模式都是采用消费端主动从Broker拉取消息的形式实现的

4.2 Push(推模式)

订阅主题及注册监听
Pull请求
返回消息或超时
Consumer
每隔一段时间循环一次
Broker
获取消息
消息队列没有数据时会阻塞
收到消息后消费

4.3 Pull(拉模式)

Pull方式里,取消息的过程需要用户自己写

  1. 首先通过Topic获取MessageQueue集合
  2. 遍历集合
  3. 针对每个MessageQueue批量取消息,记录offset

4.4 延迟级别

Broker延迟级别从1-18,对应时间1s、5s、10s、30s、1m、2m、3m、4m、5m、6m、7m、8m、9m、10m、20m、30m、1h、2h

4.5 Broker定时消息发送逻辑

获取到
获取不到
为达到投递时间
发送成功或发送异常
发送失败
开始
获取消息队列
获取消息
安排100ms后执行下次定时任务
遍历消息队列
安排Nms后执行
达到投递时间
发送消息
安排10000ms后执行定时任务

5 批量消息和事务消息

  1. 为什么使用批量消息
  2. 使用批量消息的限制
  3. RocketMQ事务消息设计
  4. 事务消息的使用约束
  5. 事务消息的状态

5.1 为什么使用批量消息

追求性能,尤其在消息量特别大的情况,将请求合并发送,如数据库批处理

5.2 使用批量消息的限制

  1. 同一批次的消息应该具有相同Topic、相同的消费配置
  2. 不支持延迟消息
  3. 建议一次批量消息不要超过1MB

5.3 RocketMQ事务消息设计

  1. MQ发布方发布Half消息到Server
  2. Half消息发送成功
  3. MQ发布方执行本地事务
  4. MQ发布方向Server发送Commit或Rollback
  5. Server未收到4的确认,回查事务状态
  6. MQ发布方检查本地事务状态
  7. MQ发布方根据事务状态向Server发送Commit或Rollback
  8. Server接收到Commit,向MQ订阅方投递消息
  9. Server接收到Rollback,删除消息不投递

5.4 事务消息的使用约束

  1. 不支持定时和批量
  2. 为了避免消息堆积,限制了单个消息的默认检查次数为15次,可以通过修改broker配置文件中的transactionCheckMax参数进行调整
  3. 特定的时间段之后才检查事务,通过broker配置文件中的transactionTimeout参数进行调整
  4. 一个事务消息可能被检查或消费多次
  5. 事务消息的生产者ID不能与其它类型消息的生产者ID共享

5.5 事务消息的状态

  1. TransactionStatus.CommitTransaction提交事务,允许消费者消费这个消息
  2. TransactionStatus.RollbackTransaction回滚事务,消息将会被删除或不再允许消费
  3. TransactionStatus.Unknown中间状态,MQ需要重新检查来确定状态

6 RocketMQ高性能最佳实践

  1. Producer最佳实践
  2. 消费者组和订阅
  3. 消息监听器
  4. NameServer最佳实践

6.1 Producer最佳实践

  1. 一个应用尽可能用一个Topic,消息子类型用tags来标识,tags可以由应用自由设置
  2. 每个消息在业务层面的唯一标识码,要设置到keys字段,方便将来定位消息丢失问题
  3. 如有可靠性需要,消息发送成功或者失败,要打印消息日志(sendresult和key信息)
  4. 如果相同性质的消息量大,使用批量消息,可以提升性能
  5. 建议消息大小不超过512kb
  6. send(msg)会阻塞,如果有性能要求,可以使用异步的方式:send(msg, callback)
  7. 对于消息不可丢失应用,务必要有消息重发机制
  8. send消息方法发送成功会有多个状态,在sendResult中定义

以上策略不一定保证消息一定发送成功,建议将消息存储到db,由后台线程定时重试,保证消息定到达Broker

6.2 消费者组和订阅

不同的消费组可以消费同样的主题,并且每个消费者都有各自的消费偏移量
确保同一消费者组的消费者订阅相同的Topic

6.3 消息监听器

关于这一部分,之后会有另一篇博客详细讲述

6.4 NameServer最佳实践

为了让Broker和Client启动后,能够向注册中心提供注册消息,有以下四种方式可以进行配置

  1. 编程的方式
  2. HTTP端点
  3. JVM配置
  4. Linux内核配置

参考文章

聊一聊顺序消息
网易云课堂《Java高级开发工程师》

结语

本人所有博客仅用于学习记录,不做任何商业用途,如涉及侵权,还请联系删除,感谢阅读,欢迎留言,一起进步~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值