目录
五种消息模型
RabbitMQ提供了6种消息模型,但是第6种其实是RPC,并不是MQ。其中3、4、5这三种都属于订阅模型,只不过进行路由的方式不同。
基本消息模型
原理
P(producer/ publisher):生产者,一个发送消息的用户应用程序。
C(consumer):消费者,消费和接收有类似的意思,消费者是一个主要用来等待接收消息的用户应用程序
队列(红色区域):rabbitmq内部类似于邮箱的一个概念。虽然消息流经rabbitmq和你的应用程序,但是它们只能存储在队列中。队列只受主机的内存和磁盘限制,实质上是一个大的消息缓冲区。许多生产者可以发送消息到一个队列,许多消费者可以尝试从一个队列接收数据。
总之:生产者将消息发送到队列,消费者从队列中获取消息,队列是存储消息的缓冲区。
消息确认机制(ACK)
RabbitMQ有一个ACK机制。 当消费者获取消息后,会向RabbitMQ发送回执ACK,告知消息已经被接收。不过这种回执ACK分两种情况:
-
自动ACK:消息一旦被接收,消费者自动发送ACK
-
手动ACK:消息接收后,不会发送ACK,需要手动调用
如果消息不太重要,丢失也没有影响,那么自动ACK会比较方便。如果消息非常重要,不容丢失。那么最好在消费完成后手动ACK,否则接收消息后就自动ACK,RabbitMQ就会把消息从队列中删除,如果此时消费者宕机,那么消息就丢失了。
work消息模型
原理
我们可以让多个消费者监听同一队列,消费者接收到消息后, 通过线程池异步消费。但是一个消息只能被一个消费者获取。workqueue常用于避免消息堆积问题。
能者多劳
调用basicQos方法设置prefetchCount = 1,这告诉RabbitMQ在消费者未处理并确认当前消息前,不要向工作人员发送新消息。 如果我们把这行代码注释后,它就能实现能者多劳,会把更多的消息分配给消费快的人
订阅模型-Fanout(广播)
原理
-
1) 可以有多个消费者
-
2) 每个消费者有自己的queue(队列)
-
3) 每个队列都要绑定到Exchange(交换机)
-
4) 生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定。
-
5) 交换机把消息发送给绑定过的所有队列
-
6) 队列的消费者都能拿到消息。实现一条消息被多个消费者消费
注意:交换机只能转发消息不能存储消息
订阅模型-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
的时候使用通配符!
Routingkey
一般都是由一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
持久化
在MQ正常运行的过程中,我们可以通过ACK机制防止消费者丢失消息,但却解决不了MQ宕机或重启的问题。这时候我们就需要用到持久化技术了
前提:队列,交换机都要设置成持久化
交换机持久化
队列持久化
消息持久化