me/MQ/RocketMQ.md
2025-03-20 14:53:47 +08:00

7.9 KiB
Raw Blame History

RocketMQ

官方网站:https://rocketmq.apache.org/zh/ 中文文档:https://rocketmq.apache.org/zh/docs/

从网上找的现成的消息传递基本流程

普通消息的使用场景

微服务解耦
异步执行事件
数据集成

生命周期

  • 初始化:生产者构建并完成初始化,待发送到服务端
  • 待消费:发送到服务端,对消费者可见,等待消费
  • 消费中:被消费者处理,服务端会等待消费完成,如果没有收到消费者的响应,会进行重试。
  • 消费提交:消费者完成消费处理,向服务端提交消费结果,服务端标记当前消息已经被处理,消费成功、失败
  • 删除消息:在消息到期或存储空间不足时,将消息从物理文件中删除

发送消息时可以设置一个key方便查询消息轨迹。这个key最好是唯一的比如订单编号、用户ID、Trace等。

延时/定时消息

生产者设置好消息的定时时间,服务端按时投递给消费者。一个典型的场景用户在业务系统中发起支付创建一笔支付单后5分钟未付款关闭支付单。

注意事项

  • 定时的时间是一个毫秒级 Unix 时间戳
  • 必须设置在24小时范围内超过范围不生效
  • 若设置在当前时间之前,服务端将立即投递

生命周期

相比普通消息,在初始化和待消费之间,加了一个定时中的状态。服务端将延时消息单独存储,到时间以后再挪到普通消息的存储位置,暴露给消费者进行消费。

⚠️如果大量的延时消息在同一时刻触发,会造成系统压力过大、消息延迟,影响定时精度,尽量打散定时时间。

顺序消息

典型的应用场景有序的事件处理、数据实时增量同步比如用canal同步mysql的binlog至ES或其他存储介质。

注事事项

顺序消息的关系是通过 Message Group 识别的,生产者发送顺序消息时,需要为每条顺序消息设置 Message Group相同 Message Group 的消息遵循 FIFO 原则。

  • 必须由同一个生产者投递,且投递到同一个 Message Group 才能保障顺序性
  • 必须串行发送,多线程得保证顺序投递消息,建议用最简单的方式单线程串行发送
存储逻辑

相同的消息组按照先后顺序存储到同一个队列,不同消息组的消息可以混在同一个队列,但是不一定连续。

事务消息

分布式和微服务应用中分布式事务是一个非常重要的组件传统的XA事务方案资源锁定范围大、并发度低。基于普通消息很难保障一致性因为普通消息没有协调提交、回滚的能力。而事务消息就是补充了普通消息的二阶段提交、与本地事务绑定的能力实现最终一致性。

  • 生产者发送消息到服务端
  • 服务端将消息持久化向生产者返回Ack确认消息发送成功
  • 此时消息被标记为"暂不能投递",这种消息叫做半事务消息
  • 生产者继续执行本地事务,然后向服务端发送事务结果:提交/回滚
  • 服务端收到事务结果后
    • 事务提交:把半事务消息让消费者可见,让消费者成功消费
    • 事务回滚:取消投递半事务消息
    • 生产者异常:如果生产者因为宕机或者重启造成不可用,或者服务端收到的事务结果是 Unknown 等异常情况
    • 事务悬挂:为了避免生产者异常造成事务悬挂,服务端将会对生产者主动发起回查,第一次检查默认间隔 60 秒支持自定义配置最多不能超过1个小时
    • 事务超时最多4个小时后超时超时将强制回滚
    • 事务回查:生产者收到服务端的回查,要检查本地事务的执行结果,服务端根据回查结果决定要不要发消息

生命周期

注意事项

事务消息只保证本地主分支事务下游消息发送事务的一致性,不能保证消息消费结果和上游事务的一致性。所以下游服务要保证自己的分支事务正确处理,并做好消费重试机制,宕机、重启这种短暂的不可用,可以直接利用服务端的重试机制。在消息提交到下游消费端处理完成之前,下游分支和上游事务之间的状态可能会不一致。因此,事务消息仅适合接受异步执行的事务场景