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 的消息,长轮询也看不到。

相关推荐
狼爷13 小时前
Rust/Go/Java/Python/PHP 大比拼:负载下后端框架到底差多少?
java·后端·编程语言
念何架构之路13 小时前
zap扩展生态与总结
java·前端·数据库
第七页独白14 小时前
汽车零件厂如何通过 QMS 真正落地 IATF 16949——QMS软件系统:品质检验-内审稽核-8d客诉管理:全星质量管理软件系统
java·前端·数据库
QCoding14 小时前
Spring AI Alibaba Graph实战:从ReAct Agent到Workflow,企业AI复杂流程该如何编排?
java·人工智能
用户0942485680314 小时前
第25章:Java虚拟线程(Project Loom)实战与调度协作
java·jvm
砚底藏山河14 小时前
量化实战:截面因子有效性检验(IC 分析与分层回测)
java·python·金融·maven
wuminyu14 小时前
ForkJoinPool内部WorkQueue的Lock-Free数组操作以及并发任务窃取原理剖析
java·linux·c语言·jvm·c++
Elastic 中国社区官方博客14 小时前
使用 Lucene 搜索你的 Bean — 索引
java·大数据·数据库·elasticsearch·搜索引擎·全文检索·lucene
code2cat15 小时前
Java进阶篇之AtomicMarkableReference:引用还在,标记已经改变
java·开发语言·cas·并发编程·逻辑删除
她说彩礼65万15 小时前
C语言 堆区和栈区
java·linux·c语言