消息中间件 Apache Qpid 简介(3)

前一部分介绍了 Qpid 的概括,希望您已经了解什么是 Qpid,可以下载安装它,并自己亲手实验几个小例子。在第二部分,我想稍微深入 Qpid 内部,澄清一些概念,加深理解,并介绍 Qpid 的几个高级特性。

作为一个消息中间件,最重要的就是性能(吞吐量)和可靠性。

为了提高性能,Qpid 可以建立 Broker Federation 来进行负载均衡,C++ 版本的 Broker 还可以利用 RDMA 来提高信息传输的性能。

Qpid 采用了很多种技术来提高可靠性。比如将消息持久化,采用 broker 集群等。

这些特性使得 Qpid 成为集群环境下的一个高性能,高可靠性的消息中间件。

查看 Queue 节点和 Topic 节点的背后

首先,我打算澄清几个概念。

如前所述,使用 Qpid 编程时,使用两类地址节点:一种是 Queue,另外一种是 Topic。假如您没有使用过 Qpid0.5 版本的 API,可能对此并没有什么特别的疑问。但对于 Qpid 的老用户,熟悉了 AMQP 模型的人来说,可能会在这里有些困惑。在介绍一些高级特性之前,我觉得应该首先澄清这个困扰我很久的问题,因为它或许也是您的疑问吧。但假如您对此不感兴趣或没有疑问,请跳过本节。

Qpid 的文档中有如下介绍:Queue 映射到 AMQP 概念就是 Queue;而 Topic 则映射到 Exchange。

不知道您如何感觉,反正我花了很长的时间来理解这句话。因为按照 AMQP,Consumer 程序总是绑定到一个 Queue 上的,而不应该直接从 Exchange 接收消息。

语言有点儿贫乏,不如画张图吧,Qpid 的模型如下图所示:


图 1. Qpid 模型

图 1. Qpid 模型

在这个模型中,假如您想和 AMPQ 模型相比较对应,就会发现 Qpid 的 Queue 节点和 AMQP 的 Queue 相对应,这尚可以理解,

但 Topic 节点和 Exchange 对应就让人费解。在 AMQP 术语中,Topic 只是 Exchange 的一种,况且 Application 也不应该直接从 Exchange 中收发消息。难道 Qpid 不符合 AMQP 么?、


图 2. AMQP 模型

图 2. AMQP 模型

可以通过 Qpid-tool 来查看这两种 Node 背后的具体实现,进而理解 Qpid 的术语和 AMQP 术语的对应关系,因为毕竟 Qpid 是 AMQP 的一个实现。

先创建一个叫做 Hello-world 的 Queue:

bash-3.2$ ./qpid-config add queue hello-world  

再用 Qpid-tool 查看到底新创建了什么东西?

bash-3.2$ qpid-tool qpid: list queue Object Summary: ID Created Destroyed Index ================================================================ 。。。在此省略一些输出 148 05:30:22 05:30:24 135.topic-sqws29.23936.1 160 05:30:24 - 135.hello-world 。。。在此省略一些输出  

可以看到名为”hello-world”的 Queue 被建立了。再查看 binding 的情况:

qpid: list binding active Object Summary: ID Created Destroyed Index ============================================================== 。。。在此省略一些输出 301 05:40:31 - 115.314.hello-world  

用 show 命令查看 bind ID 为 301 的详细情况:

qpid: show 301 Attribute 301 ========================== exchangeRef 115 queueRef 314 bindingKey hello-world arguments {} origin None msgMatched 0  

可以看到 Queue Hello-World 绑定到了 Exchange ID 为 115 的 Exchange。用 show 命令看看这个 exchange 吧:

qpid: show 115 Attribute 115 =========================== vhostRef 135 name type direct durable False 。。。在此省略一些输出  

这是一个 direct 类型的 exchange。

至此,对于 Qpid 的 Queue 节点我们有了一个完整的认识。当创建一个 Queue 节点时,Qpid 会创建一个 AMQP Queue,和一个 Binding。缺省情况下用 Queue 的名字作为 RouteKey 和一个 Direct Exchange 进行绑定。

应用程序通过 Queue 进行消息收发操作。

这样我们就把 Qpid 的 Queue 和 AMQP 完全对应了起来。

那么 Topic 节点是怎么回事儿呢?

首先建立一个 Topic Exchange。看看会发生什么?

$qpid-config add exchange topic hello-world  

用 qpid-tool 查看 exchange 的列表:

qpid: list exchange acrive Object Summary: ID Created Destroyed Index ================================================== 115 05:25:13 - 135. 116 05:25:13 - 135.amq.direct 。。。在此省略一些输出 123 05:33:14 - 135.hello-world  

可以看到此时多了一个新的名字为 hello-world 的 exchange。

但假如您用 list queue,会发现并没有新的 queue 建立起来。难道应用程序真的直接和 Exchange 通信么?

当然不可能,启动一个应用程序看看吧:

./drain – t 60 hello-world  

启动一个 Consumer 应用 Drain,其 Address 是一个 Topic 节点 hello-world。因为我们不发送消息,因此用 -t 选项指定了 60 秒的 timeout 时间,否则 Drain 会立即返回,我们没有时间查看 queue 和 exchange 的情况了。

在 drain 没有返回之前,我再次用 qpid-tool 查看了 queue 的情况:

qpid: list queue Object Summary: ID Created Destroyed Index ================================================================ 。。。在此省略一些输出 148 05:30:22 05:30:24 135.topic-sqws29.23936.1 160 05:30:24 - 135.hello-world 146 05:48:07 - 142.hello-world_4be25。。。d27b569 。。。在此省略一些输出  

可以看到在 drain 运行期间,Qpid 建立了一个临时的 queue(上图的最后一行)。

并绑定到了 hello-world 这个 exchange 上。

qpid: list binding active Object Summary: ID Created Destroyed Index =================================== 143 05:48:07 - 118.146.hello-world_4be25022-5956-4873-886d-76d59d27b569 144 05:48:07 - 123.146.# 。。。在此省略一些输出  

Binding 信息显示 Qpid 将 ID 为 123 的 exchange 和 ID 为 146 的 queue 通过 # 作为 RouteKey 绑定到了一起。

这下问题清楚了,当使用所谓 Topic 节点作为 Address 时,在底层,Qpid Client 库会自动建立所需要的 AMQP Queue 和 Binding。其底层依然符合 AMQP 的模型。只不过类似建立 binding,创建 Queue 等工作由 Qpid 的 client 库代劳了,应用程序无需考虑这些。

此外,通过这个例子,希望您也已经对 Qpid-tool 的使用有了一定的认识,在实践中,它将是 troubleshooting 的首要工具。

顺便说一下,这些工具都是 python 写的,在使用之前,需要配置 PYTHONPATH:

export PYTHONPATH=$qpid_dir/python: =$qpid_dir/extras/qmf/src/py  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/65790989a26526f210db1b69300a9c21.html