JMS
JMS(Java MessageService)实际上是指JMS API,它定义了一些借口,提供了一套标准API。
JMS提供了两种消息模型,peer-2-peer(点对点)以及publish-subscribe(发布订阅)模型。当采用点对点模型时,消息将发送到一个队列,该队列的消息只能被一个消费者消费。而采用发布订阅模型时,消息可以被多个消费者消费。在发布订阅模型中,生产者和消费者完全独立,不需要感知对方的存在。
消息如何从producer端达到consumer端由message-routing来决定。在JMS中,消息路由非常简单,由producer和consumer链接到同一个queue(p2p)或者topic(pub/sub)来实现消息的路由。JMSconsumer同时支持message selector(消息选择器),通过消息选择器,consumer可以只消费那些通过了selector筛选的消息。在JMS兄中,消息路由机制的图示如下:
![](https://i-blog.csdnimg.cn/blog_migrate/ecd442b63ae057d6bacee980927d7d63.png)
AMQP
AMQP(advanced message queuing protocol)是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。这使得实现了AMQP的provider天然性就是跨平台的。意味着我们可以使用Java的AMQP provider,同时使用一个python的producer加一个rubby的consumer。只要都按照相应的数据格式去发送报文请求,不同语言的client均可以和不同语言的server连接。
在AMQP中,消息路由(messagerouting)和JMS存在一些差别,在AMQP中增加了Exchange和binding的角色。producer将消息发送给Exchange,binding决定Exchange的消息应该发送到那个queue,而consumer直接从queue中消费消息。queue和exchange的bind有consumer来决定。AMQP的routing scheme图示过程如下:
最后将JMS和AMQP的各项对比如下:
JMS | AMQP | |
定义 | Java api | Wire-protocol |
跨语言 | 否 | 是 |
跨平台 | 否 | 是 |
Model | 提供两种消息模型: (1)、Peer-2-Peer (2)、Pub/sub | 提供了五种消息模型: (1)、direct exchange (2)、fanout exchange (3)、topic change (4)、headers exchange (5)、system exchange 本质来讲,后四种和JMS的pub/sub模型没有太大差别,仅是在路由机制上做了更详细的划分; |
支持消息类型 | 多种消息类型: TextMessage MapMessage BytesMessage StreamMessage ObjectMessage Message (只有消息头和属性) | byte[] 当实际应用时,有复杂的消息,可以将消息序列化后发送。 |
综合评价 | JMS 定义了JAVA API层面的标准;在java体系中,多个client均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差; | AMQP定义了wire-level层的协议标准;天然具有跨平台、跨语言特性。 |