RocketMQ 的基本概念

本文最后更新于:22 分钟前

RocketMQ 的基本概念

分布式消息队列

  • Producer : 消息的发送者:举例:发信者
  • consumer: 消息的接收者;举例:收信者
  • Broker:暂存和传输消息;举例:邮局
  • NameServer: 管理 broker;举例,各个邮局的管理机构
  • Topic: 区分消息的种类; 一个发送者可以发送消息给一个或者多个 Topic; 一个消息的接收者可以订阅一个或者多个 topic 消息
  • Message Queue 相当于是 Topic 的分区;用于并行发送和接收消息

发送特点区分消息类型:

  1. 同步发送

​ a. 同步发送,线程阻塞,投递 completes 阻塞结束

​ b. 如果发送失败,会在默认的超时时间 3 秒内进行重试,最多重试 2 次

​ c. 投递 completes 不代表投递成功,要 check sendResult.sendStatus 来判断是否投递成功

​ d. SendResult 里面有发送状态的枚举: SendStatus, 同步的消息投递有一个状态返回值

​ e. retry 的实现原理:只有 ack 的 SendStatus = SEND_OK 才会停止 retry

注意: 发送同步消息且 Ack 为 SEND_OK, 只代表该消息成功的写入了 MQ 当中,并不代表该消息成功的被 Consumer 消费了且消费成功了。

  1. 异步发送

​ a. 异步调用的话,当前线程一定要等待异步线程回调结束再关闭 producer ,因为是异步的,不会阻塞,提前关闭 producer 会导致未回调链接就断开了

​ b. 异步消息不回 retry, 投递失败回调 onException() 方法,只有同步消息才会 retry,源码参考 DefaultMQProducerImpl.class

​ c. 异步发送一般用于链路耗时较长,对 RT 响应时间较为敏感的业务场景,例如用户视频上传后通知启动转码服务,转码完成后通知推送转码结果等。

  1. 单向发送

​ a. 此消息不可靠,性能高,只负责往服务器发送一条消息,不会重试,也不关心是否发送成功

​ b. 此方式发送消息的过程耗时非常短,一般在微妙级

发送方式 发送 TPS 发送结果反馈 可靠性
同步 不丢失
异步 不丢失
单向 最快 可能丢失

按照特使用功能特点分:

  1. 普通消息(订阅)

​ 普通消息是我们在业务开发中用到的最多的消息类型,生产者需要关注消息发送成功即可,消费者消费到消息即可,不需要保证消息的顺序,所以消息可以大规模并发地发送和消费,吞吐量很高,适合大部分场景。

  1. 顺序消息

​ 顺序消息分为分区顺序消息和全局顺序消息,全局顺序消息比较容易理解,也就是那条消息先进入,那条消息就会先被消费,符合我们的 FIFO,很多时候全局消息的实现代价很大,所以出现了分区顺序消息。分区顺序消息的概念如下图所示

image-20220622121054408

​ 我们通过对消息的 Key ,进行 hash,相同 hash 的消息会被分配到同一个分区里面,当然如果要做全局顺序消息,我们的分区只需要一个即可,所以全局顺序消息的代价是比较大的。

  1. 延时消息 - 订单超时、库存归还

​ 延迟的机制是在服务端实现的,也就是 broker 接收到了消息,但是经过一段时间后才发送服务器按照 1 -N 定义了如下级别: “1s 5s 10s 30s 1m 2m ……. 1h 2h “ ;若要发送定时消息,在应用层初始化 message 消息对象之后,调用 Message.setDelayTimeLevel(int level) 方法来设置延迟级别,按照顺序取相应的延迟级别,例如 Level = 2,则延迟为 5s

​ 实现原理:

​ a. 发送消息的时候,如果消息设置了 DelayTimeLevel,那么该消息会被丢到 ScheduleMessageService.SCHEDULE_TOPIC 这个 topic 里面

​ b. 根据 DelayTimeLevel 选择对应的 queue

​ c. 再把真实的 topic 和 queue 信息封装起来,set 到 msg 里面

​ d. 然后每个 SCHEDULT_TOPIC_XXXXX 的每个 DelayTimeLevelQueue, 有定时任务去刷新,是否有待投递的消息

​ e. 没 10s 定时持久化发送进度

  1. 事务消息

​ 消息队列 Rocket MQ 版本提供的分布式事务消息适用于所有对数据最终一致性有强需求的场景。

概念介绍:

  • 事务消息: 消息队列 RocketMQ 提供类似 X 或者 open xa 的分布式事务功能,通过消息队列 RocketMQ 事务消息能达到分布式事务的最终一致性。
  • 半事务消息: 暂不能投递的消息,发送方已经成功地将消息发送到了消息队列 RocketMQ 版服务端,但是服务端未能收到生产者对消息的二次确认,此时该消息被标记成 暂不能投递 状态,处于该种状态下的消息即半事务消息。
  • 消息回查: 由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,消息队列 RocketMQ 版服务端通过扫描发现某条消息长期处于半事务消息 时,需要主动向生产者询问该消息的最终状态 (commit 或是 Rollback) , 该询问过程即消息回查。

分布式事务消息的优势:

消息队列 RocketMQ 版分布式事务消息,不仅可以实现应用之间的解偶,又能保证数据的最终一致性。同时,传统的大事务可以被拆分成小事务,不仅能提升效率,还不会因为某一个关联应用的不可用导致整体回滚,从而最大限度保证核心系统的可用性。在极端情况下,如果关联的某一个应用始终无法处理成功,也只需要对当前应用进行补偿或数据订正处理,而无需对整体业务进行回滚。

关注我获取更新


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!