RocketMq 消息分类

背景:在最近的几个项目中同事们总是会遇到和消息队列相关的一些问题,这些问题成功的激起了我的好奇心,因此趁着周末放假赶紧了解了一波RocketMq的一些基本的概念;

一、普通消息

区别于其他消息类型的一般消息类型

普通消息的发送方式分为三类:同步消息、异步消息和单向发送;

  • 同步消息:一条消息发送并且接受到返回消息后才发送下一条消息;
  • 常用于类似于邮件发送、短信发送的场景
  • 异步消息:一条消息发送后接着发送下一条,消息异步返回;
  • 常用于对于链路反馈及时性要求较高的场景。
  • 单向发送:一条消息发送后不需要得到反馈就继续发送消息,消息发送速度很快但是存在失败的风险。
  • 常用于耗时要求短但可靠性要求不高的场景,例如日志收集。

二、分布式事务消息

通过本地执行事务和二次确认机制来保证消息传递的最终一致性,实现分布式系统的各个应用解耦。

优点:

  • 应用程序的事务解耦和数据的最终一致性
  • 大事务可以被拆分为小事务,提升效率的同时还不会因为一个单独的小事务不可用而整体回滚,最大限度保证核心系统的可用性
  • 即使在极端情况下,某个应用始终无法执行成功,也只需要对应用采用补偿或者数据订正处理而不需要对整体业务回滚

分布式事务处理流程

  • 1、消息发送方现将消息发给消息队列的服务器端,由服务器进行消息的持久化保存
  • 2、持久化保存成功后,服务器向发送方发送ack确认消息,确认已经执行成功,此时的消息处于半事务状态
  • 3、发送方开始执行本地的事务逻辑
  • 4、事务逻辑的执行结果将会决定半事务消息是commit还是rollback:
  • 执行成功则提交,失败则回滚
  • 另外如果因为异常情况导致本地事务执行结果没有传递给服务端,那么在一段时间后将会发送消息回查消息;
  • 发送方收到回查消息后确认本地事务的执行结果后返回最终结果,并回传二次确认(另外半事务状态只能保存3天,过期会清除掉)
  • 5、消息队列的服务端收到commit状态后将半事务消息标记为可传递,订阅方最终受到该消息
notice

1、事务消息的GroupID不可以和别的类型消息的GroupID共用,因为事务消息具有回查机制,会根据GID回查服务端

2、通过ONSFactory的createTransactionFactoryProducer创建实物消息的Producer时必须指定LocalTransactionChecker的实现类,可处理异常情况下实物消息的回答

3、事务消息在完成本地事务之后可以在execute方法中返回3种状态分别代表回滚、提交和暂时无法判断状态

  • TransactionStatus.CommitTransaction
  • TransactionStatus.RollbackTransaction
  • TransactionStatus.Unknow (等待固定时间之后消息队列服务端向发送端查询本地事务执行结果,进行消息回查)
事务回查机制说明
  • 为什么必需是先回查Check机制?
  • 在本地事务执行后返回的结果为未知状态或者因为异常情况没有将本地事务执行结果回传给发送端时有必要进行回查从而确认最终状态
  • check被回调是业务逻辑需要做些什么?
  • 写一些事务一致性检查的逻辑并且向消息发送端返回半事务消息的状态

事务的订阅和普通消息订阅一致

三、定时延时消息

消息被发送端接受后不是立即推送而是会在未来的某个时间推送给消费者。

概念解释:
  • 定时消息:生产者生产的消息被推送到服务端后不需要立即的推送,而是推迟到当前时间之后的某个时间点再推送消息。
  • 延时消息:producer生产消息并推送到消息队列的服务端后消息不会立即投递,而是延迟一段时间再投递
适用场景

消息的生产和消费存在一定的时间窗口要求:例如商品订单在下单后在一定的时间范围内没有支付,超过了这个时间范围将会自动取消

notice
  • 定时消息的精度存在1~2是的延迟误差
  • 定时和延时消息的msg.setStartDeliverTime参数需要设置为当前时间戳之后的某个时刻,如果被设置为之前的某个时刻消息会立即投递出去
  • 定时和延时的最长时间为40天,超过了将会发送失败(如果想实现更长的时间可以在代码层面加上失败重试,如果超过了这个时间那么再次进行发送)
  • 客户端和服务端可能存在时间差,因此消息投递的时间可能存在误差
  • 在投递时间之后的3天是消息的保存期,在这个期间如果消息一直没有被投递,这个消息仍然可以保留。

四、顺序消息

严格按照顺序来进行消息的消费(FIFO)

  • 全局顺序:对于指定的Topic,所有的消息按照FIFO的方式进行消息的发布和消费。
  • 分区顺序:对于一个topic下的所有数据,采用shardingKey实现区块分区,同一个分区内的数据严格按照FIFO的方式进行消息的发布和消费,shardingKey是一种区别于message中普通key的一种key专门用于消息的分区

主要特性(顺序2.0)

  • FIFO:完全串行,保证数据的消费顺序
  • 高并发性:无主一致性架构极大的提高消息的吞吐量
  • 高可用性:无主一致性架构提供完善的负载均衡策略和故障节点自适应恢复能力
  • 无热点:负载均衡策略解决热点问题