消息队列的核心模型
在分布式系统设计中,消息队列(MQ)承担着异步解耦与流量削峰的关键角色。Java 标准化组织(JCP)定义的 Java 消息服务(JMS)最早明确了两种基础通信模型:点对点(Point-to-Point)与发布/订阅(Publish/Subscribe)。理解这两者的本质差异,是选型消息中间件的基础。
1. JMS 标准定义
JMS 规范主要区分了 Queue 和 Topic 两种目标类型。
点对点模式(Queue) 生产者将消息发送至队列,消费者从队列获取并消费。关键点在于:消息一旦被消费,队列中即不再保留。即使存在多个消费者,单条消息也仅能被其中一个处理。这天然支持负载均衡——多个消费者竞争同一队列中的消息。
发布/订阅模式(Topic) 生产者将消息发布到主题,所有订阅该主题的消费者都能收到一份拷贝。这与队列不同,消息会被广播给所有活跃的订阅者。
2. 深度对比分析

上图展示了典型的点对点流程。生产者发送一条消息到 Queue,只有一个消费者能收到。这种机制下,Queue 实现了可靠的负载均衡。当没有消费者可用时,消息会被保存直到有可用消费者。一个 Queue 可以关联多个消费者,它们之间共享负载。

而在发布订阅模式中,发布者发送到 Topic 的消息,只有订阅了该 Topic 的订阅者才会收到。这意味着从 1 个发布者到 N 个订阅者,每个订阅者都会得到消息的独立拷贝。只有在消息代理收到消息且存在有效订阅时,订阅者才能获取数据。
疑问解答:订阅组如何实现负载均衡?
在纯发布订阅模式下,如果单个订阅者处理能力不足,确实存在瓶颈。实际场景中,通常采用分组订阅(Consumer Group)机制。多个订阅者节点组成一个组,共同消费同一个 Topic 的消息流,从而实现消费能力的线性扩展。此时,Topic 下的消息在逻辑上表现为类似队列的分发特性。

3. 主流中间件的实现差异
虽然 ActiveMQ 严格遵循 JMS 规范,但 RabbitMQ 和 Kafka 等流行中间件并未完全照搬旧版规范,而是通过各自协议实现了更灵活的路由与消费机制。
RabbitMQ 基于 AMQP 协议,强调路由规则。生产端通过路由规则将消息投递到特定 Queue,消费端根据 Queue 名称拉取或接收推送。RabbitMQ 采用推模型,订阅关系和消费状态保存在服务端。

生产端发送一条消息通过路由投递到 Queue,只有一个消费者能消费到。



