日期:2026-07-11
标签:#面试 #八股 #后端 #系统设计 #场景题
一句话答案
推模式实时性好但容易压垮慢消费者;拉模式由消费者控制节奏、易做批处理和故障恢复,因此主流 MQ 常以长轮询实现“使用体验像推、底层机制是拉”。
对比
| 维度 | 推模式 | 拉模式 |
|---|---|---|
| 实时性 | 通常更好 | 普通轮询受间隔影响,长轮询可改善 |
| 流量控制 | Broker 需要感知消费者能力 | 消费者天然控制速率 |
| 慢消费者 | 易堆积连接和请求 | 可暂停拉取并逐步追赶 |
| 批处理 | 较难动态控制批次 | 易按条数或字节批量拉取 |
| Broker 状态 | 需要维护推送与重试状态 | 相对简单 |
| 空轮询 | 无 | 短轮询可能浪费资源 |
面试口语版
如果追求极低延迟且消费者数量和能力稳定,可以使用推;但通用 MQ 更适合拉,因为消费端最清楚自己的处理能力,可以自然做背压、批量和位点恢复。拉模式的空轮询问题可用长轮询解决:请求没消息时 Broker 暂挂,有消息或超时再返回。
面试官追问
- 长轮询如何实现?
- 拉模式下如何避免重复消费?
- Push Consumer 为什么底层仍可能是拉?
面试官追问参考答案
1. 长轮询如何实现?
消费者发起带等待时间的拉取请求;没有新消息时 Broker 不立即返回,而是登记请求并挂起。当目标分区有新消息、等待超时或连接关闭时唤醒请求。实现需限制挂起请求数量并处理取消,避免连接和内存耗尽。
2. 拉模式下如何避免重复消费?
拉取和业务处理之间无法天然构成分布式原子事务,通常采用至少一次:业务成功后提交 Offset,失败重试,消费者通过业务唯一键或幂等状态机去重。若先提交 Offset 再处理,宕机可能丢消息,所以一般不这样做。
3. Push Consumer 为什么底层仍可能是拉?
客户端 SDK 可以在后台长轮询 Broker,收到消息后再回调用户代码,从 API 体验看像推。这样既保留消费者主动控制批量、速率和 Offset 的优势,也获得接近推送的低延迟。
Join the conversation
Discuss on GitHubSign in with GitHub to comment. Both language versions share this conversation.