浅谈 AMQP 0.9.1 模型

RabbitMQ消息队列在企业开发中已经越来越常见,其是一个基于AMQP协议(Advanced Message Queuing Protocol,高级消息队列协议)的开源消息中间件。这里我们将就RabbitMQ所支持的AMQP 0.9.1协议简单地说一说

abstract.png

简介

在AMQP 0.9.1 协议中,交换机、消息队列和绑定,即构成了AMQP实体。AMQP中真正存储消息的是消息队列,交换机只是负责接收消息并根据绑定关系完成向消息队列的转发工作。其是一个可编程协议,即AMQP实体是可由开发者在客户端程序(生产者、消费者)中去声明定义,并通过绑定实现交换机和消息队列的路由,而非由中间件自身去定义。开发者只需在生产者的客户端程序中将消息发给指定的交换机即可,而在消费者的客户端程序只需通过指定的消息队列中接收、消费信息即可。消息在交换机和消息队列中的路由是根据交换机类型和一定路由规则共同所决定

基本概念

figure 1.png

  • Producer 生产者 : 生产者负责向RabbitMQ投递消息(实际上,其是向交换机投递而非消息队列)
  • RoutingKey 路由键: 生产者投递消息时所指定的参数,用于交换机根据一定的路由规则转发消息到相关消息队列中
  • Consumer 消费者 : 消费者负责从RabbitMQ的消息队列中接收消息
  • Exchange 交换机 : 生产者在向RabbitMQ投递消息时,并不能直接将消息投递到消息队列中。实际上,生产者是将消息投递到生产者所指定交换机上,不同类型的交换机具有其各自的路由规则,交换机根据一定的路由规则(使用消息所携带的RoutingKey和绑定在该交换机上的消息队列的BindingKey),再将消息转发给相应的消息队列上
  • Queue 消息队列 : 用于接收、储存交换机转发的消息,消费者通过其接收、消费消息
  • BindingKey 绑定键 : 在消息队列绑定到交换机的过程中,可以指定BindingKey参数,用于交换机根据一定的路由规则转发消息到相关消息队列中

交换机类型

如前所述,交换机的类型将决定其具体的路由规则。不同类型的交换机的路由规则,也是我们在开发中需要重点了解和掌握。在AMQP 0.9.1模型中,提供了以下四种类型的交换机:

  • Direct Exchange 直连交换机
  • Fanout Exchange 扇形交换机
  • Topic Exchange 主题交换机
  • Headers Exchange 头交换机

这里对在开发中常见的前三种交换机进行介绍

Direct Exchange

直连交换机和消息队列之间通过BindingKey完成绑定,如下图所示,绑定在交换机上的消息队列Queue2设置的BindingKey即为”dog”。与此同时,一个消息队列亦可在该交换机上绑定多个BindingKey,如下图中的消息队列Queue1在该交换机上即绑定了两个BindingKey,分别为”cat”和”pig”

生产者在向该交换机上投递消息的同时,还会携带RoutingKey一并投递。交换机将比较消息携带的RoutingKey 和 绑定在该交换机上消息队列的BindingKey是否完全一致,如果完全一致,即满足路由规则,交换机则将消息投递到该消息队列,即 “单播”

figure 2.png

当消息投递到该交换机携带的RoutingKey为”dog”时,满足路由规则的只有消息队列Queue2,交换机将转发消息到消息队列Queue2上;当消息投递到该交换机携带的RoutingKey为”cat”时,满足路由规则的有消息队列Queue1、Queue3,交换机会把消息分别转发到消息队列Queue1、Queue3上

Fanout Exchange

对于扇形交换机而言,其路由规则是最简单的,其会将收到的消息转发给绑定在其上的所有消息队列,即”广播” 。所以如下图所示,交换机和消息队列的绑定上无需指定BindingKey,而生产者投递到交换机上的消息时所携带的RoutingKey亦会被交换机所忽略

figure 3.png

Topic Exchange

主题交换机亦是利用绑定的BindingKey来作为路由规则,与直连交换机不同的是,其BindingKey必须是用 . 小数点分隔多个标识符,而对于BindingKey中的标识符数量并无其他要求。同时在BindingKey中还可以使用两种通配符

  • * : 表示匹配一个标识符
  • # : 表示匹配任意个(零个或多个)标识符

主题交换机的路由规则,是利用比较消息携带的RoutingKey 和 绑定在该交换机上消息队列的BindingKey是否匹配,如果匹配,即满足路由规则,交换机则将消息投递到该消息队列,即多播。当BindingKey中无*、#通配符时,其效果等同于直连交换机;当BindingKey为”#”时,其将接收所有消息,其效果等同于扇形交换机

figure 4.png

当消息投递到该交换机携带的RoutingKey为”black.small.dog”时,满足路由规则的有消息队列Queue2、Queue3,交换机会把消息分别转发到消息队列Queue2、Queue3上;当消息投递到该交换机携带的RoutingKey为”dog”时,满足路由规则的只有消息队列Queue2,交换机会把消息转发到消息队列Queue2上;当消息投递到该交换机携带的RoutingKey为”black.big.cat”时,满足路由规则的只有消息队列Queue1,虽然该消息队列Queue1与交换机绑定的两个BindingKey均满足路由规则,但交换机也只会把消息转发一次到消息队列Queue1中

0%