领先一步
VMware提供培训和认证,以加速您的进步。
了解更多更新 我修改了第一段,以阐明RabbitMQ和JMS之间的关系。
RabbitMQ是一个轻量级、可靠、可扩展且可移植的消息代理。但与Java开发人员熟悉的许多消息代理不同,它不基于JMS。相反,您的应用程序通过一个平台中立的线级协议与之通信:高级消息队列协议(AMQP)。幸运的是,已经有一个Java客户端库,并且SpringSource正在开发一流的Spring和Grails集成——所以不用担心必须进行低级操作才能使用RabbitMQ。您甚至可以找到公开JMS接口的AMQP客户端库。但是AMQP在操作上与JMS有很大差异,这可能会给习惯了JMS模型的Java开发人员带来麻烦。
为了简化过渡,我将在本文中介绍支撑AMQP的基本概念以及三种常见的用例场景。最后,您将希望对配置RabbitMQ并通过Spring和Grails提供的API使用它有足够的了解。
与任何消息系统一样,AMQP是一种消息协议,处理发布者和消费者。发布者生成消息,消费者接收并处理它们。消息代理(如RabbitMQ)的作用是确保发布者的消息到达正确的消费者。为此,代理使用两个关键组件:交换机和队列。下图显示了它们如何将发布者连接到消费者
如您所见,设置非常简单。发布者将消息发送到一个命名交换机,消费者从队列中提取消息(或者根据配置,队列将消息推送到消费者)。当然,首先必须建立连接,那么发布者和消费者如何相互发现呢?通过交换机的名称。通常,发布者或消费者创建一个具有给定名称的交换机,然后公开该名称。发布方式取决于具体情况,但可以将其放在公共API文档中或发送给已知的客户端。
消息如何从交换机路由到队列?好问题。首先,队列必须附加到给定的交换机。通常,消费者同时创建队列并将其附加到交换机。其次,交换机接收的消息必须与队列匹配——一个称为“绑定”的过程。
要理解绑定,了解AMQP消息的结构很有用
消息的头和属性基本上是键值对。它们之间的区别在于,头由AMQP规范定义,而属性可以包含任意特定于应用程序的信息。实际的消息内容只是一系列字节,因此,如果您想在消息中传递文本,则应标准化编码。UTF-8是一个不错的选择。如果需要,您可以在消息头中指定内容类型和编码,但这似乎并不常见。
这与绑定有什么关系?标准头之一称为路由键代理使用它来将消息与队列匹配。每个队列指定一个“绑定键”,如果该键与路由键头的值匹配,则队列接收消息。
交换机类型的概念使事情变得稍微复杂了一些。AMQP规范定义了以下四种类型
交换机类型 | 行为 |
---|---|
直接 | 绑定键必须与路由键完全匹配——不支持通配符。 |
主题 | 与直接相同,但绑定键中允许使用通配符。#匹配零个或多个点分隔的单词,*匹配恰好一个这样的单词。 |
扇出 | 路由键和绑定键被忽略——所有发布的消息都发送到所有绑定的队列。 |
头 |
更新 我更正了有关通配符的信息,通配符基于点分隔的单词或术语。
例如,假设发布者将路由键为“NYSE”的消息发送到名为“Stocks”的主题交换机。如果消费者创建一个附加到“Stocks”的队列,其绑定键为#、*或NYSE,则该消费者将收到消息,因为所有三个绑定键都匹配“NYSE”。但是,如果消息发布到直接交换机,则如果绑定键为#或*,则消费者将不会收到消息,因为这些字符被视为文字,而不是通配符。有趣的是,#.#也将匹配NYSE,尽管路由键没有点。
现在考虑一个路由键为“NYSE.TECH.MSFT”的消息。鉴于消息将发送到主题交换机,哪些绑定键将与之匹配?
绑定键 | 匹配? |
---|---|
NYSE.TECH.MSFT | 是 |
# | 是 |
NYSE.# | 是 |
*.* | 否 |
NYSE.* | 否 |
NYSE.TECH.* | 是 |
NYSE.*.MSFT | 是 |
这就是全部内容。每个队列支持多个消费者,每个交换机支持多个队列,从而提供了灵活性。实际上,单个队列甚至可以绑定到多个交换机。现在让我们看看其中一些场景。
AMQP代理可以在客户端和服务之间充当RPC机制。一般设置如下,使用直接交换机
一般顺序如下
从客户端的角度来看,调用可以是阻塞的或非阻塞的。但是,执行哪种操作的难易程度取决于正在使用的客户端库。
RPC场景的关键是确保客户端和服务对初始请求使用相同的交换机,并且客户端知道为路由键指定什么。
至于回复队列,它通常由客户端创建,然后客户端适当地填充reply_to头。此外,虽然您可以使用与请求不同的交换机来回复,但更常见的是对请求和回复都使用相同的交换机。
JMS具有主题队列的概念,该概念可确保发布者的消息发送到所有订阅者。您可以通过将多个队列绑定到交换机来轻松地在AMQP中实现相同的行为,如下所示
更好的是,队列可以通过绑定键过滤它们接收的消息。如果消费者希望接收所有消息,则可以指定绑定键为#——“匹配任意数量的单词”通配符。如前所述,对于普通开发人员来说,*匹配零个或一个(点分隔的)单词,这有点令人困惑。
假设您有一个应用程序,它有一堆需要执行的作业。使用AMQP,您可以连接多个消费者,以便每个作业都发送到一个且仅一个消费者。发布者不关心哪个消费者执行工作,只关心工作已完成。这就是工作分配。
配置非常简单,如下图所示
因此,您有一个绑定到交换机的队列,多个消费者共享该队列。此设置保证只有一个消费者处理给定的消息,无论有多少个消费者。
这些是AMQP代理的三种主要使用模式。虽然我已分别描述了每一种,但将它们组合在一起是相当常见的。例如,在RPC模式中,多个服务可以共享同一个队列(工作分配)。如何配置交换机和队列完全取决于您,现在您应该有足够的了解来确定适合您情况的适当设置。