本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
前言
日常开发中,常常使用到消息队列来进行异步解耦,比如之前曾使用消息队列来接受直播中台发来的主播开播提醒等等。
先解释一下什么叫消息队列(Message Queue)。消息队列是应用之间的一种通信方式,而消息是指在应用之间进行传输的数据。消息体没有限制,可以是简单的文本字符串,也可以是序列化之后的对象。
消息发送之后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只负责把消息发布到MQ中而不用管谁来取,消息使用者只管从MQ中取消息而不管是谁发布的,这样发送者与接收者之间就实现了解耦。同时,由于消息队列是应用间的一种异步协作机制,也可以使用消息队列来实现流量削峰,如常见的秒杀、抢红包等等,这些活动的特点在于一瞬间的请求量会激增,而当大量请求在瞬间发送到服务器的时候(高并发),就有可能导致服务器宕机。所以,为了避免此类情况的发生,一般采取将高并发量的请求拒于系统的上层,将先将这些请求放入消息队列之中,而不是直接打到服务器上。
RabbitMQ详解
RabbitMQ就是一个实现了AMQP的消息队列开源框架,支持多种主流编程语言,如C、Java、Python等,RabbitMQ具有高可靠、高可用等特点。
消息模型
所有的消息队列产品都可以将其抽象为三个部分:生产者(Producer)创建消息,然后发布到某个消息队列(Queue)当中进行保存,然后订阅了该队列的消费者(Consumer)从队列中获取消息进行消费。
RabbitMQ基本概念
下图是RabbitMQ的一个示意图
-
Producer:消息的生产者 -
Message:消息由label和payload组成-
label:消息头,是由一系列属性组成的,如routing-key(路由键)、priority(优先级)、delivery-mode(是否需要持久化存储)等; -
payload:消息体,就是传输的数据的数据
-
-
Exchange:交换机,用于接收生产者发送的消息并将这些消息通过路由规则分发到指定的队列当中 -
Queue:消息队列,用于保存生产者生产的消息,直到这些消息发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列当中。消息一直在队列里面,直到消费者将这些消息消费掉 -
Binding:绑定,用于关联交换机Exchange和队列Queue。一个绑定就是基于路由键将交换机和消息队列连接起来的路由规则,因此,也可以将交换机看做是一个由绑定构成的路由表 -
Consumer:消费者,表示从消息队列中消费消息的客户端应用程序 -
Broker:消息队列服务器实体 -
Connection:网络连接,如一个TCP连接; -
Channel:信道,多路复用连接中的一个独立的双向数据流通道。信道是建立在真实的TCP连接内地虚拟连接。不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。对于操作系统来说,建立和销毁TCP都是非常昂贵的开销,所以引入了信道的概念,以复用一条TCP连接 -
Virtual Host:虚拟主机,表示一批交换机、消息队列和相关对象。每个vhost本质上是一个mini的RabbitMQ服务器,拥有自己的队列、交换机、绑定和权限机制
几个概念详解
Exchange
生产者生产完消息之后,会将消息发送到Exchange(交换器)上,由Exchange将消息根据路由规则将消息路由到一个或多个Queue中(或者丢弃)。RabbitMQ中有三种常见的Exchange类型,分别为direct、topic和fanout,不同的类型有着不同的路由策略。如所示:
Routing key
生产者在将消息发送给交换器时,一般会指定一个路由键,来指定这个消息的路由规则,而路由键需要与交换机的类型以及绑定键联合使用才能有效。当交换机类型与绑定键固定时,通过指定的路由键,生产者发送到交换机上的消息将会被分发到指定是队列上。需要注意的是,在RabbitMQ中路由键的最大长度为255个字节。
Binding
在RabbitMQ中,交换机和队列通过Binding进行绑定关联,这样MQ就能正确的将消息路由到指定的队列上了。
在绑定交换机和队列时,一般会指定一个Binding Key。生产者将消息发送到交换机上时,一般指定一个路由键,Routing Key。而当Binding key和Routing Key相匹配时,消息将会被路由到对应的队列上。在绑定多个队列到同一个交换机时,这些Binding允许使用相同的绑定键。但绑定键并不是所有情况下都生效,当交换机类型为fanout时,交换机将会无视绑定键。
总结
简单介绍了RabbitMQ的原理及组成部分,后面会详细介绍下其在工程中的使用。