目录

  • 一、工作队列模式——work queue
  • 消息确认
  • 公平派遣
  • 消息持久化
  • 二、订阅模式——Publish/Subscribe
  • 交换器与队列的绑定
  • 三、路由模式——Routing
  • 直接交换
  • 多重绑定
  • 四、通配符模式——Topic
  • 五、RPC模式


一、工作队列模式——work queue

docker rabbitmq 队列持久化 rabbitmq队列状态_go

其工作模式采用的是多消费者消费同一队列中的信息

publisher将数据发到消息队列中,数据将默认采用循环调度的方式分配给消费者,即每一个消费者按队列的顺序依次得到相等量的数据。
仅仅这样工作存在以下问题:
1、如果一个消费者还没有处理完数据就异常退出了,那么这条数据也就作废了
2、如果某一消费者的处理时间相当长,还没有处理完上一条,mq又分配了一条,这就导致了积压,这个消费者的压力贼大。
3、如果RabbitMQ服务器停止,我们的任务仍然会丢失。RabbitMQ退出或崩溃时,除非咱告诉它不要这样做丢失队列,否则它将忘记队列和消息。
为解决这些问题,RabbitMQ还为这种工作模式提供了三种机制

消息确认

消费者发送回一个确认(acknowledgement)以告知RabbitMQ已经接收,处理了特定的消息,并且RabbitMQ可以自由删除它。
如果使用者死了(其通道已关闭,连接已关闭或TCP连接丢失)而没有发送确认,RabbitMQ将了解到消息未完全处理,并将该消息重新排队。如果同时有其他消费者在线,它将很快将其重新分发给其他消费者。这样,可以确保即使消费者偶尔死亡也不会丢失任何消息。

公平派遣

为了解决第二个问题,并且有了消息确认的基础,我们可以给每一个消费者绑定一个字段,当消费者当前没有正在处理的消息时,该字段为0,当有消息在处理时设为1,表示该消费者忙碌,RabbitMQ会将消息给下一个消费者继续这样判断。
换句话说,在处理并确认上一条消息之前,不要将新消息发送给工作人员。而是将其分派给尚不繁忙的下一个工作人员。

消息持久化

为解决第三个问题,在我们声明队列的时候将ch.QueueDeclare中的durable字段为true,表示开启持久化,这样RabbitMQ会在磁盘上做持久化,服务器宕机也没事

二、订阅模式——Publish/Subscribe

docker rabbitmq 队列持久化 rabbitmq队列状态_持久化_02


p是生产者,X是交换机,生产者把消息发给交换机,交换机把消息等份的发送到绑定它的队列,消费者监听着自己的队列,队列将消息发送给监听的消费者。

交换器与队列的绑定

有几种交换类型可用:direct,topic,headers 和fanout,官网介绍的是fanout
它是将接收到的所有消息广播到它知道的所有队列中。交换器拥有他的名字,在ch.ExchangeDeclare设置。队列也要注明绑定的哪个交换机在ch.QueueDeclare中设置。

三、路由模式——Routing

在订阅模式的基础上,给管道设置不同的key,交换机根据不同的key传给相应的管道

直接交换

docker rabbitmq 队列持久化 rabbitmq队列状态_go_03

直接交换背后的路由算法很简单:消息进入交换机的绑定密钥与消息队列的路由密钥完全匹配的队列 。
在此设置中,我们可以看到绑定了两个队列的"direct"模式的交换X。第一个队列由绑定键orange绑定,第二个队列有两个绑定,一个绑定键为black,另一个绑定为green。

在这样的设置中,使用路由键orange的消息,将由交换机分到队列Q1。路由键为黑色 或绿色的消息将转到Q2。所有其他消息将被丢弃。

多重绑定

docker rabbitmq 队列持久化 rabbitmq队列状态_字段_04


既然一个消息队列可以绑定多个路由键,当然一个路由键绑定多个队列也是合法的

这种方式有点像订阅模式

四、通配符模式——Topic

路由模式虽然能将消息放入对应的管道,但它仍然存在局限性-它无法基于多个条件进行路由。也就是说一个消息即面满足A的条件,又满足B的条件,最好把这个消息法入这两个管道
学过Linux的同学可以知道,我们用通配符find文件可以找到文件名含有通配符字段的文件

find /var/log -name 'm*'

RabbitMQ同样提供了类似的通配符模式,如果一条消息匹配了多个绑定键,则这个消息可以进入多个队列

(星号)可以代替一个单词。

#(哈希)可以替代零个或多个单词。

下面对手册中的图举个例子:

docker rabbitmq 队列持久化 rabbitmq队列状态_字段_05


交换器选用topic模式。

三类单词构成路由键:勤快程度,颜色,物种

我们创建了三个绑定:Q1与绑定键“ ✳ .orange.✳” 绑定,Q2与

“ ✳.✳.rabbit ”和“ lazy.# ” 绑定。

我感觉绑定键和路由键是一个东西,路由键是对交换器而言,而绑定键是对队列而言。就像爸爸对于我来说是爸爸,而对于妈妈来说就是老公,其实都是一个人。

假如P生产了消息:quick.orange.rabbit

到了交换机,匹配了“ ✳ .orange.✳” 和“ ✳.✳.rabbit ”两个路由,交换机会向这两个管道写入

五、RPC模式

docker rabbitmq 队列持久化 rabbitmq队列状态_go_06


RPC将像这样工作:

客户端启动时,它将创建一个匿名排他回调队列。
对于RPC请求,客户端发送一条消息,该消息具有两个属性: reply_to(设置为回调队列)和correlation_id(设置为每个请求的唯一值)。
该请求被发送到rpc_queue队列。
RPC工作程序(又名:服务器)正在等待该队列上的请求。出现请求时,它会使用reply_to字段中的队列来完成工作并将带有结果的消息发送回客户端。
客户端等待回调队列上的数据。出现消息时,它将检查correlation_id属性。如果它与请求中的值匹配,则将响应返回给应用程序。