在《消息队列在分布式系统中的应用》一文中咱们介绍了消息队列与分布式系统二者间的密切关系以及消息队列的应用场景。本篇以 RabbitMQ 为例,继续深刻了解消息队列中间件的运行方式。html
AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是一个基于应用层的异步消息服务协议,为面向消息的中间件设计提供了统一实现规范。AMQP 协议的目标是实现一种在全行业内普遍使用的标准消息中间件,解决众多消息队列供应商接口不统一的问题。RabbitMQ 就是使用 Erlang 编程语言开发的一个 AMQP 开源实现,是目前为止部署最普遍的开源消息代理和消息队列中间件。做为一个企业级消息系统,RabbitMQ 支持多种编程语言和客户端,而且自带了集群、管理、插件等功能,拥有着良好的高可用性、可扩展性和易用性。web
RabbitMQ 提供了详尽的安装文档步骤,咱们能够根据不一样的操做系统类型来进行选择。
以 Ubuntu 为例,能够执行安装指令:编程
sudo apt-get install -yq rabbitmq-server
启动 rabbitmq-server:bash
sudo service rabbitmq-server start
查看 Queues 列表:架构
sudo rabbitmqctl list_queues
在学习 RabbitMQ 的实际操做以前,首先须要掌握下列 RabbitMQ 的基本对象概念。
异步
是 RabbitMQ 的操做单元,由 Payload 有效负载和 Label 标签两部分组成,前者做为消息的主体数据,后者则包含了消息路由转发相关的描述数据。编程语言
负责生产消息,经过设定 Label 的内容来决定将消息投递到指定队列。分布式
负责接收消息并执行相应的任务,消费者仅仅会关心消息的 Payload,而无需关心消息的 Label。消费者会从订阅的队列中获取消息,若是有多个消费者订阅了同一队列,那么队列默认会以平摊的方式将消息分派给消费者。svg
是存放消息的地方,消息会在队列中以 FIFO 的方式等待取出。学习
生产者和队列之间的中转站,充当路由器的功能,将消息路由到不一样的队列中,最后再被订阅了该队列的消费者取出。
为队列和交换机创建绑定关系,只有在确立了绑定关系以后,交换机才会将消息路由到相应的队列中,每个绑定关系都会包含有一个 Binding Key。
在绑定交换机和队列时,会为这次绑定设置一个 Key 值,做为惟一标识。
消息的路由转发描述,用做消息和队列之间的匹配,会在队列绑定到交换机时设置。同时,生产者在生产消息时也为该消息指定一个路由键,以此来决定由将该消息存放到哪个队列中。实际上 Routing Key 可能还须要结合 Exchange Type 以及 Binding Key 才能最终决定路由目标。
RabbitMQ 支持 fanout、direct、topic、headers 四种交换机类型,每种类型都具备特定的消息路由策略。
fanout exchange 扇形交换机:该类型交换机会无视路由键,将同一份消息路由给绑定到扇形交换机自身的全部队列,因此扇形交换机采用的是广播路由策略。也就是说同一份消息会被分发给不一样的消费者,进而执行不一样的任务。这一特性,很是符合「单一操做,多重响应」的场景,例如:Blog 系统中的一个新建博文操做,实际上须要完成新建博文记录、更新文章计数、推送订阅邮件等多种响应。
direct exchange 直连交换机:当队列绑定到交换机以后,会为这次绑定设置一个路由键。生产者将消息发送到交换机以前,也会为消息设置一个路由键,直连交换机会经过匹配消息路由键与绑定路由键来肯定消息路由目标。因此直连交换机采用的是单播路由策略。
topic 主题交换机:在交换机与队列创建绑定时,除了会设置路由键以外还会设置一个绑定键,并且绑定键支持通配符 *(单个字符) 和 #(任意个字符)两种形式。主题交换机会经过匹配消息路由键和绑定键来肯定消息路由目标,也就是说同一个队列可以接收不一样路由键的消息(绑定键具备通配符),因此主题交换机是一种多播路由策略。须要注意的是,应用主题交换机时,消息的路由键命名格式应该是以 ’.’ 分割的单词词组。例如:路由键分别为 task.add、task.sub、task.mult 的消息都会路由到绑定键为 ‘task.#’ 的队列中。
headers 头交换机:头交换机不会依赖路由键和绑定键做为路由策略因素,而是单纯的经过消息中所包含的 AMQP 协议头信息来决定,该类型交换机由于效率问题,通常不多被用到。
本篇最为《快速入门分布式消息队列之 RabbitMQ》的上篇主要介绍了 RabbitMQ 架构的对象概念,经过了解这些对象的概念,相信可以对 RabbitMQ 的运行机理有一个初步的认识。