RocketMQ消费者消息获取

RocketMQ 消费者没有服务端主动推送 ,本质是 PULL 拉模型;所谓 PushConsumer 只是 SDK 封装的伪推送,底层依然是循环向 Broker 发拉取请求。

两种模式

  1. PullConsumer:手动调用 pull (),自己控制什么时候去拉消息。
  2. DefaultMQPushConsumer(常用):底层自动 PULL 长轮询

流程:

  1. 消费者发送 PullRequest 请求 Broker:我要拉取某一个 MessageQueue 的消息。
  2. Broker 收到请求:
    • 如果有消息:立刻把消息返回给消费者。
    • 如果没有消息 :Broker不马上返回 response,把这个 pull 请求挂起,保存到等待队列。
  3. Broker 当收到新消息写入该队列时,唤醒挂起的 pull 请求,立刻返回消息给客户端。
  4. 如果一直没有消息,等待超时(默认 30s),返回空结果;消费者收到空,马上发起下一次 pull 请求。

长轮询机制

RocketMQ 底层都是通过 Netty 框架进行的通信(异步非阻塞 IO)。消费者向 Broker 发送 pull 请求后,业务线程不会阻塞,等 Broker 返回后通过回调函数处理结果,有消息则消费消息,无消息则重新发起 pull 请求。Broker 收到请求后也不会阻塞等待,先判断有无消息,若是有消息则立即返回,没有消息则将请求加入等待队列。默认等待 30s,期间有消息则唤醒请求返回消费者,没有消息则返回空结果。

这里有几个关键点值得展开:

  • 消费者侧不阻塞:发送 pull 请求后,消费者线程可以继续做其他事情,等 Broker 响应回来再通过回调处理,因此单个消费者可以同时挂起多个 pull 请求,提升吞吐。
  • Broker 侧也不阻塞:Broker 收到 pull 请求后,如果暂时没有消息,不会让线程干等,而是把请求挂到等待队列里,释放线程资源去处理其他请求。
  • 等待队列的作用:挂起的请求会记录消费者要拉的 MessageQueue 和 offset,等新消息到达时,Broker 能精准找到对应的挂起请求并唤醒它。
  • 超时兜底:如果 30s 内一直没有新消息,Broker 会主动返回空结果,避免请求无限期挂起;消费者收到空结果后立即发起下一次 pull,形成持续的轮询循环。
  • 长轮询的价值:相比普通轮询(拉不到就立刻返回),长轮询让 Broker 帮忙"等一会儿",既减少了空轮询的次数,又能保证消息到达后尽快被消费,兼顾实时性和性能。

broker如何判断有无消息

Broker 处理 pull 请求时:

读取这个 queue 对应的 ConsumeQueue ,对比消费者提交的offset

  • 如果 offset < ConsumeQueue最大offset → 有新消息,读取返回;
  • 如果 offset 已经追到末尾,没有新消息 → 将 pull 请求挂起,进入长轮询等待。

⚠️注意:判断有无消息看 ConsumeQueue 索引 ,不直接看 CommitLog。ReputMessageService 异步把消息构建进 ConsumeQueue 之后,pull 请求才看得到这条消息。

刚写入 CommitLog 但还没构建 ConsumeQueue 的消息,长轮询也看不到。

相关推荐
逆境不可逃4 小时前
Pi Agent 学习笔记:对话太长以后,如何压缩上下文
java
MetaLite4 小时前
JDK 8~26 核心特性一览:从 Stream 到 Scoped Values
java
wno7045 小时前
Spring Boot WebFlux增删改查
java·spring boot·后端
君顾15 小时前
上海24小时自助健身房系统开发实战指南:从架构设计到落地部署
java·开发语言·健身房
SL_staff6 小时前
别急着买商业规则引擎:90%风控场景根本不需要全量编码能力
java·程序员·groovy
ManageEngineITSM7 小时前
DevOps和ITIL是什么关系?是替代还是互补一文讲清
java·服务器·资产管理·变更管理
SL_staff7 小时前
ERP排程总在纸上谈兵?JVS-APS如何用真实产能约束打通计划与执行闭环
java·人工智能·开源
xcl09257 小时前
24小时自助健身房系统软件开发实战指南:从架构到部署
java·spring boot
码少女8 小时前
Linux--多路转接之select
java·服务器·数据库
nvvas9 小时前
Java 入门(四):数组——数据的集合管理
java·开发语言