MQ消息队列的JMS规范和AMQP协议的区别

Posted 刘Java

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MQ消息队列的JMS规范和AMQP协议的区别相关的知识,希望对你有一定的参考价值。

详细介绍了JMS规范和AMQP协议的内容与区别。

1 JMS

JMS(JAVA Message Service),即Java消息服务,Java程序可以通过JMS服务进行异步的消息传输。JMS API是一个Sun公司提出的消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台通过统一的接口创建、发送、接收和读取消息,这类似于JDBC规范,与具体的厂商实现无关。

ActiveMQ 就是基于 JMS 规范实现的。

1.1 JMS消息模型

有两种模型,这也几乎是所有消息队列都有的模型:队列模型和**发布****/**订阅模型。RabbitMQ 采用队列模型,RocketMQ和Kafka 采用发布/订阅模型。

点到点(P2P)模型,发送者、接受者、消息队列。

使用队列(Queue)作为消息通信载体;满足生产者与消费者模式,一个queue可以有很多消费者,但一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。比如:我们生产者发送100条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半(也就是你一个我一个的消费)。

发布/订阅(Pub/Sub)模型,发布者、订阅者、主题。

发布订阅模型(Pub/Sub) 使用主题(Topic)作为消息通信载体,类似于广播模式;发布者发布一条消息,该消息通过主题传递给所有的订阅者。如果只有一个订阅者,那它和队列模型就基本是一样的了,该模型在功能层面上是兼容队列模型的。

2 AMQP

AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。

RabbitMQ 就是基于 AMQP 协议实现的。

2.1 AMQP消息模型

AMQP在消息的生产者以及传递信息的队列之间引入了一种间接的机制:Exchange,实现了生产者和队列的解耦。

binding是exchange和queue之间的虚拟连接,binding中可以包含binding key。Binding信息被保存到exchange中的查询表中,用于message的分发依据。

message首先到达Exchange,随后Exchange根据分发规则,匹配查询表中的routing key,当满足路由规则是,会将分发消息到对应的queue中去。

AMQP提供四种不同类型的Exchange:

  1. Direct(point-2-point点对点模式):当Message中的routing key和Binding中的binding key完全一致,那么Exchange将message发到对应的queue中。
  2. Fanout(多播模式):每个发到Fanout类型Exchange的message都会分到所有绑定的queue上去。
  3. Topic (发布-订阅模式):当Message中的routing key和Binding中的binding key符合通配符匹配规则,那么Exchange将分发到目标queue中。
  4. headers:是使用消息内容中的headers属性(一个map的形式)来匹配,通过判断headers中的键值对值能否匹配队列和交换器绑定时指定的键值对值来进行路由。

3 对比

对比方向JMSAMQP
定义Java API协议
跨语言
跨平台
支持消息类型提供两种消息模型: Peer-2-Peer和Pub/Sub提供了五种消息模型:direct exchange、fanout exchange、topic change、headers exchange、system exchange。本质来讲,后四种和JMS的pub/sub模型没有太大差别,仅是在路由机制上做了更详细的划分;
支持消息类型支持多种消息类型:StreamMessage(Java原始值的数据流)、MapMessage(一套名称-值对)、TextMessage(一个字符串对象)、ObjectMessage(一个序列化的 Java对象)、BytesMessage(一个字节的数据流)、Message (只有消息头和属性)byte[ ](二进制)
实现ActiveMQRabbitMQ

AMQP 为消息定义了线路层(wire-level protocol)的协议,而JMS所定义的是API规范。

在 Java 体系中,多个client均可以通过JMS使用统一的API进行交互,不需要应用修改代码,但是其对跨平台的支持较差。

而AMQP不从API层进行限定,而是直接定义网络交换的数据格式,无论生产者和消费者用什么语言编写,这样消息格式符合规则就能通信,这使得AMQP协议天然具有跨平台、跨语言特性。

JMS 支持TextMessage、MapMessage 等复杂的消息类型;而 AMQP 仅支持 byte[] 消息类型(复杂的类型可序列化后发送)。

由于Exchange提供的路由算法,AMQP可以提供多样化的路由方式来传递消息到消息队列,而 JMS 仅支持队列和主题/订阅方式两种。

如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!

以上是关于MQ消息队列的JMS规范和AMQP协议的区别的主要内容,如果未能解决你的问题,请参考以下文章

RabbitMQ小结

Amazon MQ 将 AMQP 消息转换为 JMS

MQ消息队列—— Java消息服务接口(JMS)

消息队列 RabbitMq 的五种形式队列

Rabbit MQ

架构设计:系统间通信(20)——MQ:消息协议(下)