简介
音讯队列中间件(Message Queue Middleware,简称为 MQ)是指利用高效牢靠的消息传递机制进行与平台无关的数据交换,并基于数据通信来进行分布式系统的集成。通过提供消息传递和音讯排队模型,它能够在分布式环境下扩大过程间的通信。
目前开源的消息中间件有很多,比拟支流的有 RabbitMQ、Kafka、ActiveMQ、RocketMQ 等。面向音讯的中间件提供了以涣散耦合的灵便形式集成应用程序的一种机制。
消息中间件实用于须要牢靠的数据传送的分布式环境。采纳消息中间件的零碎中不同的对象之间通过传递音讯来激活对方的事件,以实现相应的操作。消息中间件常被用来屏蔽各种平台及协定之间的个性,实现应用程序之间的协同,其长处在于可能在客户和服务器之间提供同步和异步的连贯,并且在任何时刻都能够将音讯进行传送或者存储转发。
消息中间件的用处能够概括如下:
- 解耦
- 冗余
- 削峰
- 可恢复性
- 程序保障
- 缓冲
- 异步通信
RabbitMQ 是采纳 Erlang 语言实现 AMQP (Advanced Message Queuing Protocol,高级音讯队列协定)的消息中间件,在易用性、扩展性、可靠性和高可用性等方面有着卓越体现。
装置
手动装置 RabbitMQ 较为繁琐,这里提供一种简略的基于 Docker 的装置形式:
docker run -d --name rabbitmq --hostname my-rabbitmq -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin [拉取的 RabbitMQ 镜像 id]
外围概念
RabbitMQ 整体上是一个生产者与消费者模型,次要负责接管、存储和转发音讯。从计算机术语层面来说,RabbitMQ 模型更像是一种交换机模型。RabbitMQ 的整体模型架构如下图所示:
Producer:生产者
生产者创立音讯,而后公布到 RabbitMQ 中。音讯个别能够蕴含 2 个局部:音讯体和标签。在理论利用中,音讯体个别是一个带有业务逻辑构造的数据,比方一个 JSON 字符串。音讯的标签用来表述这条音讯,比方一个交换器的名称和一个路由键。生产者把音讯交由 RabbitMQ,RabbitMQ 之后会依据标签把音讯发送给感兴趣的消费者(Consumer)。
Consumer:消费者
消费者连贯到 RabbitMQ 服务器,并订阅到队列上。在音讯路由的过程中,音讯的标签会抛弃,存入到队列中的音讯只有音讯体,消费者也只会生产到音讯体。
Broker:服务节点
对于 RabbitMQ 来说,一个 RabbitMQ Broker 能够简略地看作一个 RabbitMQ 服务节点,或者 RabbitMQ 服务实例。大多数状况下也能够将一个 RabbitMQ Broker 看作一台 RabbitMQ 服务器。
Queue:队列
RabbitMQ 的生产者生产音讯并最终投递到队列中,消费者能够从队列中获取音讯并生产。 多个消费者能够订阅同一个队列,这时队列中的音讯默认会被均匀摊派(Round-Robin,即轮询)给多个消费者进行解决,而不是每个消费者都收到所有的音讯并解决,RabbitMQ 不反对队列层面的播送生产。
Exchange:交换器
生产者并不会间接将音讯发送到队列,而是将音讯发送到交换器,由交换器将音讯路由到一个或者多个队列中。如果路由不到,会依据配置返回给生产者或者间接抛弃。 交换器有四种类型,不同的类型有不同的路由策略。
BindingKey:绑定键
RabbitMQ 中通过绑定将交换器与队列关联起来,在绑定的时候个别会指定一个绑定键 ,这样 RabbitMQ 就晓得如何正确地将音讯路由到队列了。
RoutingKey:路由键
生产者将音讯发给交换器的时候,个别会指定一个 RoutingKey,用来指定这个音讯的路由规定,而这个 RoutingKey 须要与交换器类型和绑定键联结应用能力最终失效。 交换器会依据本身的类型对路由键和绑定键进行匹配,匹配胜利则将音讯转发到对应的队列中。
Connection:连贯
无论是生产者还是消费者,都须要和 RabbitMQ Broker 建设 TCP 连贯,这个连贯就是 Connection。
Channel:信道
一旦 TCP 连贯建设起来,客户端就能够创立一个 AMQP 信道,每个信道都会被指派一个惟一的 ID。信道是建设在 Connection 之上的虚构连贯,RabbitMQ 解决的每条 AMQP 指令都是通过信道实现的。
注:在多线程利用场景下,每个线程对应一条信道,复用同一条连贯,这样能够进步性能,同时也便于管理。
交换器类型
RabbitMQ 罕用的交换器类型有 fanout、direct、topic、headers 这四种。
fanout
fanout 类型交换器会把所有发送到该交换器的音讯路由到所有与该交换器绑定的队列中,会屏蔽掉路由键、绑定键的作用。
direct
direct 类型交换器会把音讯路由到那些 BindingKey 和 RoutingKey 齐全匹配的队列中。
topic
topic 类型的交换器在匹配规定上进行了扩大,它与 direct 类型的交换器类似,也是将音讯路由到 BindingKey 和 RoutingKey 相匹配的队列中,但这里的匹配规定有些不同,它有上面这些约定:
- RoutingKey 为一个点号“.”分隔的字符串,如“com.rabbitmq.client”。
- BindingKey 和 RoutingKey 一样也是点号“.”分隔的字符串。
- BindingKey 中能够存在两种非凡字符串“*”和“#”,用于做含糊匹配,其中“#”用于匹配一个单词,“#”用于匹配一个或多个单词(能够是零个)。
headers
headers 类型的交换器不依赖于路由键的匹配规定来路由音讯,而是依据发送的音讯内容中的 headers 属性进行匹配。在绑定队列和交换器时制订一组键值对,当发送音讯到交换器时,RabbitMQ 会获取到该音讯的 headers,比照其中的键值对是否齐全匹配队列和交换器绑定时指定的键值对,如果齐全匹配则音讯会路由到该队列,否则不会路由到该队列。headers 类型的交换器性能很差,而且也不实用,基本上不会看到它的存在。
运行流程
当初总结一下 RabbitMQ 的整个应用流程。首先是生产者:
- 生产者连贯到 RabbitMQ Broker,建设一个连贯,开启一个信道。
- 生产者申明一个交换器,并设置相干属性,比方交换机类型、是否长久化等。
- 生产者申明一个队列并设置相干属性,比方是否排他、是否长久化、是否主动删除等。
- 生产者通过路由键将交换器和队列绑定起来。
- 生产者发送音讯至 RabbitMQ Broker,其中蕴含路由键、交换器等信息。
- 相应的交换器依据接管到的路由键查找相匹配的队列。
- 如果找到,则将从生产者发送过去的音讯存入相应的队列中。
- 如果没有找到,则依据生产者配置的属性抉择抛弃还是回退给生产者。
- 敞开信道。
- 敞开连贯。
对于消费者:
- 消费者连贯到 RabbitMQ Broker,建设一个连贯,开启一个信道。
- 消费者向 RabbitMQ Broker 申请生产相应队列中的音讯(推模式),可能会设置相应的回调函数,以及做一些筹备工作。
- 期待 RabbitMQ Broker 回应并投递相应队列中的音讯,消费者接管音讯。
- 消费者确认(ack)接管到的音讯。
- RabbitMQ 从队列中删除相应曾经被确认的音讯。
- 敞开信道。
- 敞开连贯。