RabbitMQ消息中间件
为什么要使用消息队列
解耦
异步
削峰
消息队列缺点
- 系统可用性降低
- 系统复杂度提高
- 一致性问题
常见消息中间件的区别
AMQP的基本概念
消息(Message):由有效载荷(playload)和标签(label)组成。其中有效载荷即传输的数据。
生产者(producer):创建消息,发布到代理服务器(Message Broker)
代理服务器(Message Broker):接收和分发消息的应用,RabbitMQ Server就是消息代理服务器,其中包含概念很多,以RabbitMQ 为例:信道(channel)、队列(queue)、交换器(exchange)、路由键(routing key)、绑定(binding key)、虚拟主机(vhost)等
消费者(consumer):连接到代理服务器,并订阅到队列(queue)上,代理服务器将发送消息给一个订阅的/监听的消费者,消费者其只能接收消息的一部分:有效载荷(playload)
RabbitMQ的消息模型
组件介绍
P(producer/ publisher):生产者,一个发送消息的用户应用程序。
C(consumer):消费者,消费和接收有类似的意思,消费者是一个主要用来等待接收消息的用户应用程序。
队列(红色区域):rabbitmq内部类似于邮箱的一个概念。虽然消息流经rabbitmq和你的应用程序,但是它们只能存储在队列中。队列只受主机的内存和磁盘限制,实质上是一个大的消息缓冲区。许多生产者可以发送消息到一个队列,许多消费者可以尝试从一个队列接收数据。
X(Exchanges):交换机一方面:接收生产者发送的消息。另一方面:知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。
常用的5种消息模型
基本消息模型
生产者将消息发送到队列,消费者从队列中获取消息,队列是存储消息的缓冲区。
work消息模型
工作队列或者竞争消费者模式
让多个消费者绑定到一个队列,共同消费队列中的消息。队列中的消息一旦消
费,就会消失,因此任务是不会被重复执行的
订阅模型(三类)
1、1个生产者,多个消费者
2、每一个消费者都有自己的一个队列
3、生产者没有将消息直接发送到队列,而是发送到了交换机
4、每个队列都要绑定到交换机
5、生产者发送的消息,经过交换机到达队列,实现一个消息被多个消费者获取的目的
Exchange类型有以下几种:
- Fanout:广播,将消息交给所有绑定到交换机的队列
- Direct:定向,把消息交给符合指定routing key 的队列
- Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
- Headers:当消息发送到RabbitMQ时会取到该消息的headers与Exchange绑定时指定的键值对进行匹配,headers属性是一个键值对,可以是Hashtable,键值对的值可以是任何类型。而fanout,direct,topic 的路由键都需要要字符串形式的。(不常用)
根据交换机的类型将订阅模型又细分为三类。
订阅模型-Fanout
主要特点是广播模式, 队列的消费者都能拿到消息。实现一条消息被多个消费者消费
订阅模型-Direct
P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。
X:Exchange(交换机),接收生产者的消息,然后把消息递交给 与routing key完全匹配的队列
C1:消费者,其所在队列指定了需要routing key 为 error 的消息
C2:消费者,其所在队列指定了需要routing key 为 info、error、warning 的消息
订阅模型-Topic
Topic 类型的 Exchange 与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。只不过 Topic 类型 Exchange 可以让队列在绑定 Routing key 的时候使用通配符。
通配符规则:
- #:匹配一个或多个词
- *:匹配不多不少恰好 1 个词
RabbitMQ如何保证消息可靠性
确保rabbitMQ消息的可靠性要做到三点:
- publisher confirms(发布方确认):
确保producer到broker节点消息的可靠性。如可能发生消息到了broker但是还没有投递到queue,broker突然宕机这种情况; - message持久化:
将message存储到硬盘,如果是未持久化的消息会存在内存中,broker宕机后重启内存中的消息会丢失 - acknowledgement(consumer确认):
该机制能够保证,只有consumer成功消费了消息,才将其从queue中移除。