源码分析RocketMQ顺序消息消费实现原理

pullRequest, offset, brokerBusy);

if (brokerBusy) {

log.info("[NOTIFYME]the first time to pull message, but pull request offset larger than broker consume offset. pullRequest: {} NewOffset:

{}", pullRequest, offset);

}

pullRequest.setLockedFirst(true);

pullRequest.setNextOffset(offset);

}

} else {

this.executePullRequestLater(pullRequest, PULL_TIME_DELAY_MILLS_WHEN_EXCEPTION);

log.info(“pull message later because not locked in broker, {}”, pullRequest);

return;

}

}

根据 PullRequest 拉取消息。如果处理队列未被锁定,则延迟拉取消息,也就说消息消费需要在ProceeQueue 队列被自己锁定的情况下才会拉取消息,否则将 PullRequest 延迟3s再拉取。并且PullRequest 的初始拉取点在拉取时只在第一次拉取时设置。

3、消息顺序消息消费


实现类:org.apache.rocketmq.client.impl.consumer.ConsumeMessageOrderlyService

3.1核心属性与构造函数

这里写图片描述

  • private final static long MAX_TIME_CONSUME_CONTINUOUSLY =

Long.parseLong(System.getProperty(“rocketmq.client.maxTimeConsumeContinuously”, “60000”));

MAX_TIME_CONSUME_CONTINUOUSLY :消费任务一次运行的最大时间。可以通过-Drocketmq.client.maxTimeConsumeContinuously来设置,默认为60s。

  • DefaultMQPushConsumerImpl defaultMQPushConsumerImpl:消息消费者实现类。

  • DefaultMQPushConsumer defaultMQPushConsumer:消息消费者。

  • MessageListenerOrderly messageListener:顺序消息消费监听器。

  • BlockingQueue< Runnable> consumeRequestQueue:消息消费任务。

  • ThreadPoolExecutor consumeExecutor:消息消费线程池。

  • String consumerGroup:消息消费组。

  • MessageQueueLock messageQueueLock:消息消费队列锁,其内如实现为:

这里写图片描述

构造方法如下:

public ConsumeMessageOrderlyService(DefaultMQPushConsumerImpl defaultMQPushConsumerImpl,

MessageListenerOrderly messageListener) {

this.defaultMQPushConsumerImpl = defaultMQPushConsumerImpl;

this.messageListener = messageListener;

this.defaultMQPushConsumer = this.defaultMQPushConsumerImpl.getDefaultMQPushConsumer();

this.consumerGroup = this.defaultMQPushConsumer.getConsumerGroup();

this.consumeRequestQueue = new LinkedBlockingQueue(); // @1

this.consumeExecutor = new ThreadPoolExecutor(

this.defaultMQPushConsumer.get(),

this.defaultMQPushConsumer.getConsumeThreadMax(),

1000 * 60,

TimeUnit.MILLISECONDS,

this.consumeRequestQueue,ConsumeThreadMin

new ThreadFactoryImpl(“ConsumeMessageThread_”)); // @2

this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl(“ConsumeMessageScheduledThread_”));

//@3

}

代码@1:创建任务拉取队列,注意,这里使用的是无界队列。

代码@2:创建消费者消费线程池,注意由于消息任务队列 consumeRequestQueue 使用的是无界队列,故线程池中最大线程数量取自 consumeThreadMin。

代码@3:创建调度线程,该线程主要调度定时任务,延迟延迟消费等。

### 如何实现 RocketMQ顺序消息消费 #### 方法和配置 为了确保业务逻辑的严格顺序,在某些特定的应用场景下,如订单管理和支付系统中,可以采用 RocketMQ 提供的顺序消息机制来满足需求[^1]。 RocketMQ 支持两种类型的顺序消息消费:分区顺序消息(Partition Ordered Messages)以及全局顺序消息(Global Ordered Messages),二者均能确保消息按照既定顺序被处理,不过具体实施细节有所区别[^4]。 对于想要利用 RocketMQ 进行顺序消息消费的情况来说,重要的一点在于要让所有的消息都进入同一个队列之中。因为 RocketMQ 能够保证的是单一队列内部的消息有序性而非跨多个队列间的整体有序性。这意味着当设计应用程序架构时,应该考虑如何将具有关联关系的数据分配至同一队列里去,从而达到保持这些数据之间相对次序的目的[^3]。 另外,如果开发者希望基于 Java 开发环境构建自己的应用,则可以通过引入 `rocketmq-client` 依赖项的方式快速集成 RocketMQ 功能模块,并在此基础上编写相应的生产者(Producer) 和消费者 (Consumer) 组件代码片段[^5]: ```xml <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.5.1</version> </dependency> ``` 在设置 Consumer 配置参数的过程中,需要注意指定合适的监听器类型以支持顺序消息模式下的回调函数执行流程控制;同时也要合理规划线程池大小等资源管理策略以便更好地适应实际运行环境中可能出现的各种负载状况。 #### 关键要点总结 - 使用 RocketMQ 实现顺序消息消费可应用于需维持操作序列化的场合; - 存在一个前提条件即所有待排序的消息必须落入相同的 Message Queue 中; - 应区分理解 Partition Ordered Messages 和 Global Ordered Messages 两者的适用范围及其差异之处; - 借助于 rocketmq-client 工具包简化开发过程并提高效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值