RabbitMQの关键知识整理

说明

RabbitMQ 作为一个转发服务器,里面涉及了一些实体的东西,如下:

  • 生产者 (Producter)
  • 消息 (Message)
  • 交换机 (Exchange)
  • 队列 (Queue)
  • 消费者 (Consumer)

在这些实体的东西的基础上,RabbitMQ 重点的是 交换机,队列

交换机与队列

说完实体的东西之后,在 交换机队列 之间有许多的规则(玩法),我们增加了如下内容:

  • 队列名 (Queue_name)

  • 交换机类型 (Exchange_type)

  • 路由键 (Routing_key)

交换机类型、路由键的作用

路由键一般可以设置为某一类相同属性定义的集合

  • fanout (扇形类型) : 忽略了 Routing_key,类比广播模式,也算是类比发布者、订阅者模式

  • direct (直接类型) : 不忽略 Routing_key,为普通String,当 N 个 Consumer 绑定的 Routing_key 一致的时候,和fanout 类型没区别

  • topics (话题类型) : 不忽略 Routing_key,Routing_key 额外加多以个规则,如果需要为单词列表的时候,需要用 . 号进行分割,例如(c.a.i),除此之外,* 可以代表一个占位符,# 可以代表 0 或者多个占位符,例如(*.a.i),(c.#)

  • headers (头部类型) : 略略略…日后补充

各类知识

交换机分发请求到队列

一个队列对应 N 个消费者

交换机分发请求的时候,用到了 Queue_nameRouting_key,默认情况下(同一个队列),交换机分发的策略是循环调度,例如,我现在有 2 个消费者,对应一个队列,分别叫C1,C2,第一次消息,队列会发送到C1,第二次消息,队列会发送到C2,以此循环调用。

这里会产生几个问题:

  • 如果 C1 是一个耗时(sleep 1s)的操作,但是 C2 是一个立刻执行完毕的队列。当前队列接受了交换机转发过来的 14 个消息,那么交换机会以循环调度的方式进行执行,消息的分配那么平均,C1 处理了 7 个消息的时候,C2 处理了 7 个消息,只不过 C2 进程会先完成任务,快将近一半的时间。

对策:RabbitMQ 中有一个qos的概念,这个概念可以帮助类比网络模型里面的epoll模式,当其中一个消费者空闲的时候,就把消息转发到该消费者上,在这种情况下的话,大大提高了整体消息消费的速率。但是也有弊端,就是如果所有的消费者都处于忙碌的状态的话,那么久可能需要考虑一下增加多一些消费者了。

  • 如果消费者消费不及时,那么在队列中就会大量堆积消息,占用大量内存,导致服务器宕机或者 RabbitMQ 宕机,并且宕机的时候,大量消息随时面临了丢失的可能,这将会产生是否可怕的严重的后果

对策:RabbitMq 中有一个持久化的概念,持久化支持队列持久化,消息持久化,为的就是防止宕机的时候,这些消息也跟之丢失。

  • 消费者因为某些系统错误结束了,理论上,该消息会转发给另外一个正在运行的消费者去消费,如果这个时候,这个消费者也宕了,那么消息将会在队列中存储,直到下一个消费者连接的时候,会投递到消费者中。

对策:设定 ack 应答机制实现高可用的特性。