RocketMQ-延迟消息处理流程

本文深入探讨RocketMQ的延迟消息功能,详细介绍了其预设的延迟时间间隔、消息处理流程及定时任务启动机制,为开发者提供全面理解。

概述

RocketMQ 支持发送延迟消息,但不支持任意时间的延迟消息的设置,仅支持内置预设值的延迟时间间隔的延迟消息;

预设值的延迟时间间隔为:1s、 5s、 10s、 30s、 1m、 2m、 3m、 4m、 5m、 6m、 7m、 8m、 9m、 10m、 20m、 30m、 1h、 2h;

在消息创建的时候,调用 setDelayTimeLevel(int level) 方法设置延迟时间;

broker在接收到延迟消息的时候会把对应延迟级别的消息先存储到对应的延迟队列中,等延迟消息时间到达时,会把消息重新存储到对应的topic的queue里面。

Broker处理延迟消息

CommitLog.putMessage()

        //获取消息的sysflag
        final int tranType = MessageSysFlag.getTransactionValue(msg.getSysFlag());
        //非事务消息 或 已commit事务消息
        if (tranType == MessageSysFlag.TRANSACTION_NOT_TYPE
            || tranType == MessageSysFlag.TRANSACTION_COMMIT_TYPE) {
            // Delay Delivery 判断消息是否设置延迟
            if (msg.getDelayTimeLevel() > 0) {
                //判断延迟级别是否大于最大级别,如果大于最大值,则将延迟级别设置为最大级
                if (msg.getDelayTimeLevel() > this.defaultMessageStore.getScheduleMessageService().getMaxDelayLevel()) {
                    msg.setDelayTimeLevel(this.defaultMessageStore.getScheduleMessageService().getMaxDelayLevel());
                }
                //延迟消息的topic为 SCHEDULE_TOPIC_XXXX
                topic = ScheduleMessageService.SCHEDULE_TOPIC;
                //获取延迟级别,一个延迟级别对应一个Queue
                queueId = ScheduleMessageService.delayLevel2QueueId(msg.getDelayTimeLevel());

                // Backup real topic, queueId
                //消息原始的topic,queueid保存到消息的property中
                MessageAccessor.putProperty(msg, MessageConst.PROPERTY_REAL_TOPIC, msg.getTopic());
                MessageAccessor.putProperty(msg, MessageConst.PROPERTY_REAL_QUEUE_ID, String.valueOf(msg.getQueueId()));
                msg.setPropertiesString(MessageDecoder.messageProperties2String(msg.getProperties()));

                msg.setTopic(topic);
                msg.setQueueId(queueId);
            }
        }

1、判断消息类型,如果是非事务消息、已commit事务消息,才能处理延迟消息
2、判断消息是否设置延迟级别,如果延迟级别大于0,则该消息为延迟消息
3、判断延迟级别是否大于最大级别,如果大于最大值,则将延迟级别设置为最大级
4、延迟消息的topic为 SCHEDULE_TOPIC_XXXX
5、获取延迟级别,一个延迟级别对应一个Queue
6、消息原始的topic,queueid保存到消息的property中
7、修改消息的topci、queueid

启动延迟消息定时任务

ScheduleMessageService.start()

延迟消息投递

`rocketmq-spring-boot-starter` 和 `rocketmq-client-java` 是 Apache RocketMQ 提供的两个不同层次的客户端工具,分别适用于不同的应用场景和开发框架。以下是两者的主要区别和特点: ### 1. 定位和适用场景 `rocketmq-client-java` 是 RocketMQ 的原生 Java 客户端库,提供了对 RocketMQ 所有核心功能的访问接口,包括消息的发送、消费、事务消息延迟消息等。它适用于任何 Java 项目,尤其是那些没有使用 Spring Boot 框架的项目。开发者需要手动配置和管理 Producer、Consumer、NameServer 地址等参数,并处理底层的连接和异常[^1]。 `rocketmq-spring-boot-starter` 是基于 `rocketmq-client-java` 的封装,专为 Spring Boot 项目设计。它通过 Spring Boot 的自动配置机制简化了 RocketMQ 客户端的集成,使得开发者可以通过简单的配置文件(如 `application.yml` 或 `application.properties`)完成 RocketMQ 的初始化和使用。它更适合在 Spring Boot 项目中快速集成 RocketMQ 功能,减少了手动配置和管理的复杂性[^2]。 ### 2. 使用方式和配置 在使用 `rocketmq-client-java` 时,开发者需要手动编写代码来创建和管理生产者(`DefaultMQProducer`)和消费者(`DefaultMQPushConsumer`)实例,并在代码中指定 NameServer 地址、主题(Topic)、标签(Tag)等参数。例如: ```java DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName"); producer.setNamesrvAddr("127.0.0.1:9876"); producer.start(); ``` 而在 `rocketmq-spring-boot-starter` 中,这些配置可以通过 `application.yml` 文件完成: ```yaml rocketmq: producer: group: my-group namesrv-addr: 127.0.0.1:9876 ``` 同时,可以通过注入 `RocketMQTemplate` 来直接发送和消费消息,无需手动管理底层资源: ```java @Autowired private RocketMQTemplate rocketMQTemplate; rocketMQTemplate.convertAndSend("test-topic", "Hello RocketMQ"); ``` 这种方式极大地简化了 RocketMQ 在 Spring Boot 项目中的集成流程[^3]。 ### 3. 功能支持 `rocketmq-client-java` 提供了完整的 RocketMQ 功能支持,包括同步发送、异步发送、单向发送、拉取模式、事务消息等。开发者可以根据需求灵活地使用这些功能。 `rocketmq-spring-boot-starter` 在此基础上进行了封装,虽然也支持大部分常用功能,但某些高级特性可能需要通过自定义配置或扩展实现。例如,在某些版本中可能存在对事务消息支持不完善的情况,或者需要额外的依赖配置来启用特定功能[^4]。 ### 4. 版本兼容性 由于 `rocketmq-spring-boot-starter` 是基于 `rocketmq-client-java` 的封装,因此其版本通常与 RocketMQ 核心客户端版本保持一致或存在一定的依赖关系。在使用时需要注意版本匹配问题,尤其是在 Spring Boot 3.x 等新版本框架中,可能会出现兼容性问题,需要选择合适的 starter 版本[^5]。 ### 5. 适用框架 `rocketmq-client-java` 适用于所有 Java 项目,包括传统的 Spring Framework 项目、Java EE 项目以及非 Spring 项目。 `rocketmq-spring-boot-starter` 则专为 Spring Boot 项目设计,提供了与 Spring Boot 生态系统的良好集成,如自动配置、依赖注入、健康检查等功能。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值