【RocketMQ】RocketMQ的特性(顺序、事务等)

3 篇文章 0 订阅
2 篇文章 0 订阅

顺序消息(Orderly Message)

  • 顺序保证:RocketMQ 支持严格的全局顺序消息和分区顺序消息。生产者发送的消息可以按照特定顺序消费,确保某些场景下的业务逻辑(例如交易处理、库存扣减)不会因为并发消费而出现混乱。
  • 实现方式:通过将消息发送到相同的队列(Queue),并确保消费端也是按顺序从同一队列拉取消息。

开发人员视角下某个topic的顺序消息其实就是“全局顺序消息”,即:生产者按照业务流转顺序发出消息、最终消费者按照同样的顺序消费到消息;
全局顺序消息并不是一方单独能保证的,这里要看,生产者怎么做、MQ内部怎么做、消费者怎么做

  • 生产者怎么做:全局顺序消息的前提是,生产者至少保证按照他想要的顺序发出,即假如MQ服务本身支持了顺序消息,那也得生产者配合按顺序来发给我,集群部署的某个服务,明显是实现不了的(多个节点同时在发送消息),所以如果业务要求顺序消息,通常需要只有一个服务节点来处理逻辑并负责同步发送(当前消息发送时要确保上个消息发送成功)
  • MQ内部怎么做:这里需要关注RocketMQ的某个Topic的消息分布,无视物理节点(Broker)的话,但从逻辑角度看,某个Topic的消息是分散在多个Queue的,非顺序消息保证下,会按照预设的负载均衡发往不同的Queue,不同的Queue大概率对应了不同的消费者,这么看来,同个Queue下消费顺序是有保障的,但是多个Queue是局部顺序的(eg: 1、2、3、4、5、6、7、8、9被放到两个Queue中,分别是1、3、4、6、9和2、5、7、8,消费的时候分别消息,极端情况下顺序是1、3、4、6、9、2、5、7、8),所以MQ内部需要保证顺序Topic都发送到一个固定的Queue去,这个可以通过代码层次的参数实现;
  • 消费者怎么做:基于以上生产者和MQ的配置,现在只有一个Queue负责当前Topic,那么从MQ拉出的消息至少是顺序的了,那么消费者按照这个顺序来消费就可,同样的道理,只能单节点消费了;
  • 总结:顺序消费当然没问题,但是需要弃用生产者、消费者、MQ的并发能力

事务消息(Transaction Message)

  • 支持分布式事务:RocketMQ 提供了事务消息功能,允许在分布式系统中实现类似于两阶段提交的事务机制。通过事务消息,用户可以确保消息的发送与业务逻辑的处理保持一致,避免不一致问题。
  • 实现原理:事务消息分为三步:
    • 消息半提交:生产者发送消息但未真正提交。
    • 本地事务执行:执行本地业务逻辑,如数据库更新等。
    • 消息最终提交或回滚:根据本地事务的执行结果决定消息是否提交或回滚。如果网络异常或进程崩溃,RocketMQ 会通过回查机制来确认事务状态。

分布式一致性保证利器:举一个例子:

  • 背景:服务A内部逻辑:数据落库 + 发送MQ;
  • 问题:先落库:数据落库成功之后发送MQ失败,消息无法补发;
  • 问题:先发MQ:消息发送成功,数据库落库失败,本地事务回滚、消息误发;
  • 以上两个场景,都有其他的补偿机制,比如第一个可以跑个定时任务来扫描发送失败的消息加入补偿机制,第二个可以补发冲抵消息,不过需要下游配合补偿机制;
  • 但是事务消息这个利器,降维打击,直接保证一致性;

定时消息和延迟消息(Scheduled/Delayed Message)

  • 定时消息:RocketMQ 支持在指定的时间点发送消息,例如在某个时刻触发某种业务逻辑。
  • 延迟消息:支持消息延迟投递,用户可以设定消息的延迟时间(例如延迟10秒再发送消息)。这是通过时间轮(time wheel)机制实现的。
  • 用途场景:延迟任务处理、定时通知等业务。

定时、延迟消息原理都是一样的,最新版的RocketMQ都是基于时间轮(底层是一个环形数组),所谓的时间轮可以这么理解:由多个节组成的首尾相连的一个圆环,新来的定时/延迟消息会被放到某个节上,时间轮随时间旋转,不断吐出当前节点里的MQ、把他放到正常的Consume里面,之后的处理和普通的消息无差别了
还有个细节点就是,时间轮这个结构是放在内存的,这意味着重启丢失,好在时间轮这个东西是支持重建的(根据CommitLog里面的原始消息数据)

消息回溯(Message Retrying/Message Rewind)

  • 消费失败后的重试:RocketMQ 支持消息消费失败后的自动重试机制。消费失败的消息不会立即丢弃,系统会按照设定的策略进行重试。
  • 消息回溯(Rewind):支持消息的回溯功能,允许消费者重新消费之前已经消费过的消息。可以通过时间或偏移量设置起始消费点,实现消息的重复处理。

看过我的上一篇:文件/数据结构视角的RocketMQ 就知道,每个消费者都对应一个某个ConsumeQueue的消费偏移值,这个偏移值是支持客户端修正的,现在看消息回溯,那不就是更新一下这个偏移值的事儿嘛,简单喽

消息过滤(Message Filtering)

  • Tag 过滤:RocketMQ 支持基于消息标签(Tag)的过滤机制。生产者可以给消息打上不同的标签,消费者可以通过订阅指定的标签来只消费感兴趣的消息。这在减少消费者的负载、提高消费效率方面具有很大帮助。
  • SQL 过滤:RocketMQ 还支持基于 SQL 的消息过滤功能。消费者可以基于消息属性(Message Property)进行复杂的 SQL 过滤,这提供了更灵活的过滤条件。

这里的消息过滤和index也就是索引结构无关,index用来查询消息,这里只是做一些简单的过滤

广播模式(Broadcasting Mode)

  • 广播消费:在默认情况下,RocketMQ 采用集群消费模式,即一个消息只会被一个消费者消费。而在广播模式下,消息会被同一消费组下的所有消费者消费。这种模式适合需要广播通知的场景,比如系统告警。

数据压缩

  • 支持压缩大消息:RocketMQ 提供了大消息压缩功能。当消息体过大时(默认大于4KB),RocketMQ 会对消息进行压缩,以减少消息传输时的网络带宽消耗,提高传输效率。

简单一句话:生产者端用LZ4压缩、Broker原封不动放入CommitLog发出的时候加一个压缩标志、消费者解压缩

死信队列(Dead Letter Queue, DLQ)

  • 处理消费失败的消息:如果某个消息多次消费失败(默认16次),RocketMQ 会将该消息移入死信队列。死信队列中的消息不会再被普通消费者处理,但可以通过专门的消费者或管理工具对这些消息进行特殊处理,例如人工干预或进一步分析。

tips:每个Topic的死信都维护一个死信队列,对应实际的物理文件是一个单独的ConsumeQueue(和正常的消息不同的文件)

消息轨迹(Message Trace)

  • 消息追踪功能:RocketMQ 提供了消息轨迹功能,可以跟踪消息从生产到消费的完整链路,帮助开发人员排查消息在传输和处理过程中的问题。这对于分析消息丢失、延迟、重复等问题非常有用。
  • 实现:消息轨迹会记录每个消息的生命周期中的关键事件,包含生产时间、消费时间、延迟等信息,通常通过独立的日志系统存储。

本质是维护一个特殊的Topic,每个消息的关键时间都会被放到这个Topic对应的队列中

多租户支持(Multi-Tenancy)

  • 多租户场景:RocketMQ 支持多租户架构,这允许不同的租户使用相同的 RocketMQ 集群而互不干扰。通过在主题(Topic)或命名空间(Namespace)上进行隔离,来实现不同租户的独立消息存储和消费。

多协议支持

  • 虽然 RocketMQ 原生支持自定义的二进制协议,但它也支持多个其他的通信协议,比如:
    • HTTP 支持:允许使用 HTTP API 与 RocketMQ 进行消息交互。
    • MQTT 支持:通过支持 MQTT 协议,可以让 IoT 设备通过 MQTT 协议进行消息的生产和消费。

总结

RocketMQ 提供了一系列特殊功能,如顺序消息、事务消息、延迟消息、消息回溯、死信队列、消息追踪等,来支持高复杂度的分布式系统需求。这些功能不仅提高了系统的稳定性和可靠性,还为各种业务场景提供了更灵活的消息处理方式,广泛应用于金融、电子商务、物联网等领域。
内容原创、有问题欢迎大家交流指正,转载注明原处~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值