背景知识
JMS一个在Java标准化组织(JCP)内开发的标准(代号JSR 914)。2001年6月25日,Java消息服务发布JMS 1.0.2b,2002年3月18日Java消息服务发布 1.1.
Java消息服务(JavaMessage Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
点对点 与 发布订阅 最初是由JMS定义的。这两种模式主要 区别或解决的问题 就是 发送到队列的消息能否重复消费(多订阅)
1.JMS中定义
JMS规范目前支持两种消息模型: 点对点 (point to point, queue)和 发布/订阅 (publish/subscribe,topic)。
点对点
消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费消息。这里要注意: 消息被消费以后,queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。 Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。发布/订阅
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。 和点对点方式不同,发布到topic的消息会被所有订阅者消费。
2.二者分析与区别
2.1 点对点模式
生产者发送一条消息到queue,只有一个消费者能收到。
2.2 发布订阅模式
发布者发送到topic的消息,只有订阅了topic的订阅者才会收到消息。
小结
queue实现了负载均衡, 一个消息只能被一个消费者接受 ,当没有消费者可用时,这个消息会被保存直到有 一个可用的消费者, 一个queue可以有很多消费者 ,他们之间实现了 负载均衡 ,所以 Queue实现了一个可靠的负载均衡 。 topic实现了发布和订阅, 当你发布一个消息,所有订阅这个topic的服务都能得到这个消息 ,所以从1到N个订阅者都能得到一个消息的拷贝,只有 在消息代理收到消息时有一个有效订阅时的订阅者才能得到这个消息的拷贝 。疑问
发布订阅模式 下,能否实现订阅者 负载均衡消费 呢?当发布者消息量很大时,显然单个订阅者的处理能力是不足的。实际上现实场景中是多个订阅者节点组成一个 订阅组 负载均衡消费topic消息,即 分组订阅(如下图所示) ,这样订阅者很容易实现消费能力 线性扩展 。
3.流行的消息队列模型比较
传统企业型消息队列ActiveMQ 遵循了JMS规范,实现了 点对点 和 发布订阅 模型,但其他流行的消息队列 RabbitMQ 、 Kafka 并没有遵循老态龙钟的JMS规范,是通过什么方式实现 消费负载均衡 、 多订阅 呢?
3.1 RabbitMQ
RabbitMQ 实现了AQMP协议,AQMP协议定义了 消息路由 规则和方式。生产端通过路由规则发送消息到不同queue,消费端根据queue名称消费消息。此外 RabbitMQ 是向消费端 推送 消息, 订阅关系 和 消费状态 保存在服务端。
生产端发送一条消息通过 路由 投递到Queue, 只有一个消费者能消费到 。
当 RabbitMQ 需要支持 多订阅 时,发布者发送的消息通过 路由 同时写到多个Queue,不同 订阅组 消费此消息。
RabbitMQ 既支持 内存队列 也支持 持久化队列 ,消费端为 推(push) 模型,消费状态和订阅关系由服务端负责维护,消息消费完后 立即删除 ,不保留历史消息。所以支持多订阅时,消息会多个拷贝。
3.2 Kafka
Kafka只支持 消息持久化 ,消费端为 拉(pull) 模型,消费状态和订阅关系由客户端端负责维护,消息消费完后 不会立即删除 ,会保留历史消息。因此支持多订阅时,消息只会存储一份就可以了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
原文链接:https://blog.csdn.net/lizhitao/article/details/47723105
查看更多关于kafka 消息队列中点对点与发布订阅的区别说明的详细内容...