消息队列学习(二)-RabbitMQ入门

1、RabbitMQ简介

RabbitMQ是采用erlang语言实现AMQP(Advanced Message Queuing protocol,高级消息队列协议)的消息中间件,它最初起源于金融系统,用于在分布式系统中存储转发消息。

RabbitMQ发展到今天,被越来越多的人认可,这和它在易用性,通用性,可靠性和可扩展性等方面的卓越表现是分不开的。RabbitMQ的具体特点被概括为以下几点:

  • 可靠性
  • 灵活的路由:在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能,RabbitMQ提供了一些内置的交换器来实现,
  • 扩展性:多个RabbitMQ可以组成一个集群,也可以根据实际业务情况动态的扩展集群中的节点。
  • 高可用性:队列可以在集群中的机器设置镜像,使得在部分节点出现问题的情况下队列仍然可用。
  • 支持多种协议:除了原生支持AMQP协议外,还支持STOMP,MQTT等多种消息中间件协议。
  • 多语言客户端:几乎支持所有的常用语言,比如java,Python,Ruby,PHP,C#,javascript等。
  • 易用的管理界面:提供一个用户界面,可以监控和管理消息、集群中的节点等。安装好RabbitMQ就自带管理界面。
  • 插件机制:提供了许多插件,以实现从多方面进行扩展,当然也可以编写自己的插件。

2、核心概念

消息队列学习(二)-RabbitMQ入门_第1张图片

  • 生产者、生产消息的一方
  • 消费者、消费消息的一方

消息一般由2部分组成,消息头和消息体,消息体可以成为payload,消息体是不透明的,而消息头则由一些列的可选属性组成,包括routing-key(路由键),priority(相对于其他消息的优先权),delivery-mode(指出该消息可能需要永久性存储等)。生产者把消息交给RabbitMQ后,根据消息头把消息发给感兴趣的消费者。

  • 交换器,消息经过交换器把消息分配到对应的消息队列中去。

Exchange(交换器)用来接收生产者的消息并将这些消息路由服务器中的队列去,如果路由不到,或许会返还给生产者,或许被丢弃掉,

交换器的4种类型:不同的类型对应着不同的路由策略,direct,topic,fanout,headers

交换器示意图如下:

消息队列学习(二)-RabbitMQ入门_第2张图片

生产者将消息发给交换器的时候,一般会指定一个RoutingKey(路由键),用来指定这个消息的路由规则,而这个RoutingKey需要与交换器类型和绑定键联(BindingKey)合使用才能最终生效。

RabbitMQ通过Binding(绑定)与Exchange(交换器)与Queue(消息队列)关联起来,在绑定的时候一般会指定一个BindingKey,这样RabbitMQ就知道如何将消息路由到指定的消息队列了,

Binding示意图:

消息队列学习(二)-RabbitMQ入门_第3张图片

生产者将消息发送给交换器时,需要一个RoutingKey,当BindingKey和RoutingKey相匹配时,消息就会被路由到相应的队列中。在绑定多个多列到同一交换器的时候,这些绑定允许使用的相同的BindingKey。BindingKey并不是在所有情况下都生效,它依赖于交换器的类型,比如fanout类型的交换器就会无视,而是将消息路由到所有绑定到该交换器的队列中。

  • 消息队列,

用来保存消息直到发送给消费者,它是消息的容器也是消息的终点。一个消息可以投入一个或者多个队列。消息一直在队列里等待消费者连接到这个队列将其取走。

RabbitMQ中的消息只能存在队列中,这一点和kafka这种消息中间件相反。kafka将消息存储在topic这个逻辑层面,而相对应的队列逻辑只是topic实际存储中的位移标识。

多个消费者可以订阅同一个队列,消息会被平均分摊(Round-Robin,轮询)给多个消费者处理,避免消息被重复消费。

RabbitMQ 不支持队列层面的广播消费,如果有广播消费的需求,需要在其上进行二次开发,这样会很麻烦,不建议这样做。

  • Broker(消息中间件的服务节点)

一个RabbitMQ Broker可以简单地看作一个RabbitMQ节点,或者RabbitMQ服务实例。大多数情况下可以将一个RabbitMQ Broker看作一台RabbitMQ服务器。

消息队列学习(二)-RabbitMQ入门_第4张图片

  • Exchange Types

常用的由direct(默认),fanout,topic,headers四种。

  • fanout

将所有发送到交换器的消息路由到所有与他绑定的队列中,不做任何判断操作,所以速度最快。

  • direct

把消息路由到那些BandingKey与RoutingKey完全匹配的队列中。

消息队列学习(二)-RabbitMQ入门_第5张图片

发送消息的时候设置路由键为warning,那么消息会路由到Queue1,Queue2中。

发送消息的时候设置路由键为info,debug,那么消息会路由到Queue2中。

以其他路由键发送消息,则消息不回路由到这2个队列中。

常用来处理有优先级的任务,根据任务的优先级把消息发送到对应的队列,这样可以指派更多的资源去处理优先级更高的队列。

  • topic

消息队列学习(二)-RabbitMQ入门_第6张图片

和direct类似,允许模糊匹配。

路由键为 “com.rabbitmq.client” 的消息会同时路由到 Queuel 和 Queue2;

路由键为 “com.hidden.client” 的消息只会路由到 Queue2 中;

路由键为 “com.hidden.demo” 的消息只会路由到 Queue2 中;

路由键为 “java.rabbitmq.demo” 的消息只会路由到Queuel中;

路由键为 “java.util.concurrent” 的消息将会被丢弃或者返回给生产者(需要设置 mandatory 参数),因为它没有匹配任何路由键。

  • headers(不推荐)

根据发送消息内容中的headers属性进行匹配。在绑定队列和交换器时制定一组键值对,当发送消息到交换器时,RabbitMQ会获取到该消息的headers(键值对)对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果完全匹配则路由到该队列。性能差,不实用。

RabbitMQ安装文档见安装文章。

你可能感兴趣的:(学习)